ibanity 1.5.0 → 1.9.1

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +27 -0
  3. data/.github/workflows/gem-push.yml +29 -0
  4. data/CHANGELOG.md +29 -1
  5. data/README.md +1 -1
  6. data/lib/ibanity/api/base_resource.rb +50 -20
  7. data/lib/ibanity/api/isabel_connect/access_token.rb +1 -0
  8. data/lib/ibanity/api/isabel_connect/bulk_payment_initiation_request.rb +4 -2
  9. data/lib/ibanity/api/isabel_connect/refresh_token.rb +3 -1
  10. data/lib/ibanity/api/isabel_connect/token.rb +39 -0
  11. data/lib/ibanity/api/ponto_connect/account.rb +5 -0
  12. data/lib/ibanity/api/ponto_connect/bulk_payment.rb +20 -0
  13. data/lib/ibanity/api/ponto_connect/integration.rb +10 -0
  14. data/lib/ibanity/api/ponto_connect/onboarding_details.rb +10 -0
  15. data/lib/ibanity/api/ponto_connect/reauthorization_request.rb +10 -0
  16. data/lib/ibanity/api/ponto_connect/sandbox/financial_institution_transaction.rb +8 -0
  17. data/lib/ibanity/api/sandbox/financial_institution_transaction.rb +10 -0
  18. data/lib/ibanity/api/xs2a/financial_institution_country.rb +10 -0
  19. data/lib/ibanity/api/xs2a/transaction.rb +10 -5
  20. data/lib/ibanity/client.rb +75 -6
  21. data/lib/ibanity/collection.rb +10 -0
  22. data/lib/ibanity/http_signature.rb +28 -5
  23. data/lib/ibanity/version.rb +1 -1
  24. data/lib/ibanity.rb +9 -2
  25. data/spec/lib/ibanity/base_resource_spec.rb +42 -0
  26. data/spec/spec_helper.rb +6 -0
  27. data/spec/support/fixture.rb +8 -0
  28. data/spec/support/fixtures/json/relationships/data_with_type.json +21 -0
  29. data/spec/support/fixtures/json/relationships/data_without_type.json +20 -0
  30. data/spec/support/fixtures/json/relationships/meta_with_type.json +20 -0
  31. data/spec/support/fixtures/json/relationships/no_links_related.json +15 -0
  32. metadata +23 -4
  33. data/.travis.yml +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8764b1c890efb8ca4d619b84264ba4fcd0a10cdbd6d1fd505da2b733662d329c
4
- data.tar.gz: a44447ecf5aec8045ade36f08702f8a134f98d5eff010843ba730902dfd0552e
3
+ metadata.gz: 69d8a3c866e929ec613b9b17c146269217889e0e498b7f5c9fe0a84c0db5b643
4
+ data.tar.gz: 68ccaee907f5082fa520acbaee93a4591fe888575f479a1b3c71e6432191cd48
5
5
  SHA512:
6
- metadata.gz: 8a30ada191b9256e197c851ff8c09dd9cfc89c3b72ac28c0c726da288dd925868c944f7f461cd40af55a28499ae7581718e2ef4a471dd36531e312b776c7fca1
7
- data.tar.gz: 94d709de117a166321a587cf5db08b2fea8657547fc4a3dd1cf2844c68db4d9fa63d72ed3a2d56f43639c31400831ab611ac6081d545835af2146bfd09f60248
6
+ metadata.gz: 8825787922d34faf6745621d921377e1e187d542eb26b487a6071075db654399d5f3f7d5110c2028bcb9720f29f28f219a73374fc019a217ba3eb812eaead62c
7
+ data.tar.gz: a43e981bcc792e9541bd17ce01290921ca1ae9b9676221e234cc574214537dca60bccd15b66b349dd392eb8dd1d9f878109b27a708b0e7d6e2637d2685c06752
@@ -0,0 +1,27 @@
1
+ name: Ruby CI
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - name: Set up Ruby
12
+ uses: ruby/setup-ruby@v1
13
+ with:
14
+ ruby-version: 2.6
15
+ - name: Install dependencies
16
+ run: bundle install
17
+ - name: Run tests
18
+ run: bundle exec rspec
19
+ - name: Notify slack failure on master branch
20
+ if: contains(github.ref, 'master') && failure()
21
+ env:
22
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
23
+ uses: voxmedia/github-action-slack-notify-build@v1.1.2
24
+ with:
25
+ channel: ibanity-support-tech
26
+ status: FAILED
27
+ color: danger
@@ -0,0 +1,29 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build + Publish
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - name: Set up Ruby 2.6
15
+ uses: actions/setup-ruby@v1
16
+ with:
17
+ ruby-version: 2.6
18
+
19
+ - name: Publish to RubyGems
20
+ run: |
21
+ mkdir -p $HOME/.gem
22
+ touch $HOME/.gem/credentials
23
+ chmod 0600 $HOME/.gem/credentials
24
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
25
+ gem build *.gemspec
26
+ gem push *.gem
27
+ rm -rf $HOME/.gem/credentials
28
+ env:
29
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9
4
+
5
+ * [Ponto Connect] Add account reauthorization requests
6
+
7
+ * [Isabel Connect] Deprecate `Ibanity::IsabelConnect::AccessToken` and `Ibanity::IsabelConnect::RefreshToken`, please use `Ibanity::IsabelConnect::Token` instead
8
+
9
+ ## 1.8
10
+
11
+ * [XS2A] Update sandbox transactions
12
+
13
+ * [XS2A] Add support to list updated transaction using `synchronization_id`
14
+
15
+ * [Ponto Connect] Add support to BulkPayments
16
+
17
+ * [Isabel Connect] Add `hideDetails` and `isShared` parameters to `BulkPaymentInititationRequest.create`
18
+
19
+ ## 1.7
20
+ ### Enhancements
21
+
22
+ * [Ponto Connect] Add support for the /onboarding-details endpoint.
23
+
24
+ ## 1.6
25
+ ### Enhancements
26
+
27
+ * [Ponto Connect] Added a new revoke account endpoint. It allows to remove an account from your integration. (The bank account will not be deleted from the Ponto account itself).
28
+
29
+ * [Ponto Connect] Added a new delete organization integration endpoint. It provides an alternative method to revoke the integration (in addition to the revoke refresh token endpoint). This endpoint remains accessible with a client access token, even if your refresh token is lost or expired.
30
+
3
31
  ## 1.5
4
32
 
5
33
  * Proper release of previous enhancements
@@ -18,7 +46,7 @@
18
46
 
19
47
  ### Enhancements
20
48
 
21
- * Default signature algorithm is now ["hs2019"](https://tools.ietf.org/html/draft-cavage-http-signatures-12#appendix-E.2)
49
+ * Default signature algorithm is now ["hs2019"](https://tools.ietf.org/html/draft-cavage-http-signatures-12#appendix-E.2)
22
50
  * Add support for periodic and bulk payments
23
51
  * Add snake-case transformation for deeply nested data structures
24
52
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://travis-ci.org/ibanity/ibanity-ruby.svg?branch=master)](https://travis-ci.org/ibanity/ibanity-ruby)
1
+ ![Ruby CI](https://github.com/ibanity/ibanity-ruby/workflows/Ruby%20CI/badge.svg?branch=master)
2
2
 
3
3
  # Ibanity Ruby Library
4
4
 
@@ -86,6 +86,8 @@ module Ibanity
86
86
  private
87
87
 
88
88
  def prepare_attributes(raw)
89
+ raise "Unexpected raw type, expected hash, got #{raw}" unless raw.is_a?(Hash)
90
+
89
91
  base = {
90
92
  "id" => raw["id"],
91
93
  }
@@ -97,21 +99,47 @@ module Ibanity
97
99
 
98
100
  def setup_relationships(relationships, customer_access_token = nil)
99
101
  relationships.each do |key, relationship|
100
- if relationship["data"]
101
- klass = relationship_klass(key)
102
- method_name = Ibanity::Util.underscore(key)
103
- define_singleton_method(method_name) do |headers: nil|
104
- klass.find_by_uri(uri: relationship["links"]["related"], headers: headers, customer_access_token: customer_access_token)
105
- end
106
- self[Ibanity::Util.underscore("#{key}_id")] = relationship["data"]["id"]
107
- else
108
- singular_key = key[0..-2]
109
- klass = relationship_klass(singular_key)
110
- method_name = Ibanity::Util.underscore(key)
111
- define_singleton_method(method_name) do |headers: nil, **query_params|
112
- uri = relationship["links"]["related"]
113
- klass.list_by_uri(uri: uri, headers: headers, query_params: query_params, customer_access_token: customer_access_token)
114
- end
102
+ url = relationship.dig("links", "related")
103
+ id = relationship.dig("data", "id")
104
+
105
+ if url
106
+ setup_relationship(customer_access_token, key, relationship, url)
107
+ elsif id
108
+ self[Ibanity::Util.underscore("#{key}_id")] = id
109
+ end
110
+ end
111
+ end
112
+
113
+ def setup_relationship(customer_access_token, key, relationship, url)
114
+ if relationship["data"]
115
+ resource = relationship.dig("data", "type") || key
116
+ klass = relationship_klass(resource)
117
+ method_name = Ibanity::Util.underscore(key)
118
+ define_singleton_method(method_name) do |headers: nil|
119
+ klass.find_by_uri(uri: url, headers: headers, customer_access_token: customer_access_token)
120
+ end
121
+ self[Ibanity::Util.underscore("#{key}_id")] = relationship.dig("data", "id")
122
+ elsif relationship["meta"]
123
+ resource = relationship.dig("meta", "type")
124
+ klass = relationship_klass(resource)
125
+ method_name = Ibanity::Util.underscore(key)
126
+ define_singleton_method(method_name) do |headers: nil|
127
+ klass.find_by_uri(uri: url, headers: headers, customer_access_token: customer_access_token)
128
+ end
129
+ elsif relationship.dig("links", "meta", "type")
130
+ resource = relationship.dig("links", "meta", "type")
131
+ klass = relationship_klass(resource)
132
+ method_name = Ibanity::Util.underscore(key)
133
+ define_singleton_method(method_name) do |headers: nil|
134
+ klass.list_by_uri(uri: url, headers: headers, customer_access_token: customer_access_token)
135
+ end
136
+ else
137
+ resource = key
138
+ singular_resource = resource[0..-2]
139
+ klass = relationship_klass(singular_resource)
140
+ method_name = Ibanity::Util.underscore(resource)
141
+ define_singleton_method(method_name) do |headers: nil, **query_params|
142
+ klass.list_by_uri(uri: url, headers: headers, query_params: query_params, customer_access_token: customer_access_token)
115
143
  end
116
144
  end
117
145
  end
@@ -124,11 +152,13 @@ module Ibanity
124
152
 
125
153
  def relationship_klass(name)
126
154
  camelized_name = Ibanity::Util.camelize(name)
127
- enclosing_module = if camelized_name == "FinancialInstitution"
128
- Ibanity::Xs2a
129
- else
130
- Object.const_get(self.class.to_s.split("::")[0...-1].join("::"))
131
- end
155
+ enclosing_module =
156
+ if camelized_name == "FinancialInstitution"
157
+ Ibanity::Xs2a
158
+ else
159
+ Object.const_get(self.class.to_s.split("::")[0...-1].join("::"))
160
+ end
161
+
132
162
  enclosing_module.const_get(camelized_name)
133
163
  end
134
164
  end
@@ -2,6 +2,7 @@ module Ibanity
2
2
  module IsabelConnect
3
3
  class AccessToken < Ibanity::OAuthResource
4
4
  def self.create(refresh_token:, idempotency_key: nil)
5
+ warn "WARNING: Ibanity::IsabelConnect::AccessToken.create is deprecated, please use Ibanity::IsabelConnect::Token.create instead"
5
6
  uri = Ibanity.isabel_connect_api_schema["oAuth2"]["accessTokens"]
6
7
  arguments = [
7
8
  ["grant_type", "refresh_token"],
@@ -1,7 +1,7 @@
1
1
  module Ibanity
2
2
  module IsabelConnect
3
3
  class BulkPaymentInitiationRequest < Ibanity::BaseResource
4
- def self.create(access_token:, raw_content:, filename:, idempotency_key: nil)
4
+ def self.create(access_token:, raw_content:, filename:, idempotency_key: nil, is_shared: true, hide_details: false)
5
5
  uri = Ibanity.isabel_connect_api_schema["bulkPaymentInitiationRequests"].sub("{bulkPaymentInitiationRequestId}", "")
6
6
  create_file_by_uri(
7
7
  uri: uri,
@@ -11,7 +11,9 @@ module Ibanity
11
11
  idempotency_key: idempotency_key,
12
12
  headers: {
13
13
  content_type: :xml,
14
- "Content-Disposition": "inline; filename=#{filename}"
14
+ "Content-Disposition": "inline; filename=#{filename}",
15
+ "Is-Shared": is_shared,
16
+ "Hide-Details": hide_details
15
17
  }
16
18
  )
17
19
  end
@@ -2,6 +2,7 @@ module Ibanity
2
2
  module IsabelConnect
3
3
  class RefreshToken < Ibanity::OAuthResource
4
4
  def self.create(authorization_code:, redirect_uri:, idempotency_key: nil)
5
+ warn "WARNING: Ibanity::IsabelConnect::RefreshToken.create is deprecated, please use Ibanity::IsabelConnect::Token.create instead"
5
6
  uri = Ibanity.isabel_connect_api_schema["oAuth2"]["refreshTokens"]["create"]
6
7
  arguments = [
7
8
  ["grant_type", "authorization_code"],
@@ -13,8 +14,9 @@ module Ibanity
13
14
  payload = URI.encode_www_form(arguments)
14
15
  create_by_uri(uri: uri, payload: payload, idempotency_key: idempotency_key)
15
16
  end
16
-
17
+
17
18
  def self.delete(token:)
19
+ warn "WARNING: Ibanity::IsabelConnect::RefreshToken.delete is deprecated, please use Ibanity::IsabelConnect::Token.delete instead"
18
20
  uri = Ibanity.isabel_connect_api_schema["oAuth2"]["refreshTokens"]["revoke"]
19
21
  arguments = [
20
22
  ["token", token],
@@ -0,0 +1,39 @@
1
+ module Ibanity
2
+ module IsabelConnect
3
+ class Token < Ibanity::OAuthResource
4
+ def self.create(refresh_token: nil, authorization_code: nil, redirect_uri: nil, idempotency_key: nil)
5
+ uri = Ibanity.isabel_connect_api_schema["oAuth2"]["token"]
6
+ arguments =
7
+ if refresh_token
8
+ [
9
+ ["grant_type", "refresh_token"],
10
+ ["refresh_token", refresh_token],
11
+ ["client_id", Ibanity.client.isabel_connect_client_id],
12
+ ["client_secret", Ibanity.client.isabel_connect_client_secret]
13
+ ]
14
+ elsif authorization_code
15
+ [
16
+ ["grant_type", "authorization_code"],
17
+ ["code", authorization_code],
18
+ ["client_id", Ibanity.client.isabel_connect_client_id],
19
+ ["client_secret", Ibanity.client.isabel_connect_client_secret],
20
+ ["redirect_uri", redirect_uri]
21
+ ]
22
+ end
23
+ payload = URI.encode_www_form(arguments)
24
+ create_by_uri(uri: uri, payload: payload, idempotency_key: idempotency_key)
25
+ end
26
+
27
+ def self.delete(token:)
28
+ uri = Ibanity.isabel_connect_api_schema["oAuth2"]["revoke"]
29
+ arguments = [
30
+ ["token", token],
31
+ ["client_id", Ibanity.client.isabel_connect_client_id],
32
+ ["client_secret", Ibanity.client.isabel_connect_client_secret]
33
+ ]
34
+ payload = URI.encode_www_form(arguments)
35
+ create_by_uri(uri: uri, payload: payload)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -10,6 +10,11 @@ module Ibanity
10
10
  uri = Ibanity.ponto_connect_api_schema["accounts"].sub("{accountId}", id)
11
11
  find_by_uri(uri: uri, customer_access_token: access_token)
12
12
  end
13
+
14
+ def self.delete(access_token:, id:)
15
+ uri = Ibanity.ponto_connect_api_schema["accounts"].sub("{accountId}", id)
16
+ destroy_by_uri(uri: uri, customer_access_token: access_token)
17
+ end
13
18
  end
14
19
  end
15
20
  end
@@ -0,0 +1,20 @@
1
+ module Ibanity
2
+ module PontoConnect
3
+ class BulkPayment < Ibanity::BaseResource
4
+ def self.find(access_token:, account_id:, id:)
5
+ uri = Ibanity.ponto_connect_api_schema["account"]["bulkPayments"].sub("{accountId}", account_id).sub("{bulkPaymentId}", id)
6
+ find_by_uri(uri: uri, customer_access_token: access_token)
7
+ end
8
+
9
+ def self.create(account_id:, access_token: nil, **attributes)
10
+ uri = Ibanity.ponto_connect_api_schema["account"]["bulkPayments"].gsub("{accountId}", account_id).gsub("{bulkPaymentId}", "")
11
+ create_by_uri(uri: uri, resource_type: "bulkPayment", attributes: attributes, customer_access_token: access_token)
12
+ end
13
+
14
+ def self.delete(id:, account_id:, access_token:)
15
+ uri = Ibanity.ponto_connect_api_schema["account"]["bulkPayments"].gsub("{accountId}", account_id).gsub("{bulkPaymentId}", id)
16
+ destroy_by_uri(uri: uri, customer_access_token: access_token)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ module Ibanity
2
+ module PontoConnect
3
+ class Integration < Ibanity::BaseResource
4
+ def self.delete(client_access_token:, organization_id:)
5
+ uri = Ibanity.ponto_connect_api_schema["organizations"]["integration"].sub("{organizationId}", organization_id)
6
+ destroy_by_uri(uri: uri, customer_access_token: client_access_token)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Ibanity
2
+ module PontoConnect
3
+ class OnboardingDetails < Ibanity::BaseResource
4
+ def self.create(client_access_token:, **attributes)
5
+ uri = Ibanity.ponto_connect_api_schema["onboardingDetails"]
6
+ create_by_uri(uri: uri, resource_type: "onboardingDetails", attributes: attributes, customer_access_token: client_access_token)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Ibanity
2
+ module PontoConnect
3
+ class ReauthorizationRequest < Ibanity::BaseResource
4
+ def self.create(account_id:, access_token:, **attributes)
5
+ uri = Ibanity.ponto_connect_api_schema["account"]["reauthorizationRequests"].gsub("{accountId}", account_id)
6
+ create_by_uri(uri: uri, resource_type: "reauthorizationRequest", attributes: attributes, customer_access_token: access_token)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -25,6 +25,14 @@ module Ibanity
25
25
  .sub("{financialInstitutionTransactionId}", "")
26
26
  create_by_uri(uri: uri, resource_type: "financialInstitutionTransaction", attributes: attributes, customer_access_token: access_token)
27
27
  end
28
+
29
+ def self.update(access_token:, id:, financial_institution_id:, financial_institution_account_id:, **attributes)
30
+ uri = Ibanity.ponto_connect_api_schema["sandbox"]["financialInstitution"]["financialInstitutionAccount"]["financialInstitutionTransactions"]
31
+ .sub("{financialInstitutionId}", financial_institution_id)
32
+ .sub("{financialInstitutionAccountId}", financial_institution_account_id)
33
+ .sub("{financialInstitutionTransactionId}", id)
34
+ update_by_uri(uri: uri, resource_type: "financialInstitutionTransaction", attributes: attributes, customer_access_token: access_token)
35
+ end
28
36
  end
29
37
  end
30
38
  end
@@ -31,6 +31,16 @@ module Ibanity
31
31
  find_by_uri(uri: uri)
32
32
  end
33
33
 
34
+ def self.update(id:, financial_institution_user_id:, financial_institution_id:, financial_institution_account_id:, idempotency_key: nil, **attributes)
35
+ path = Ibanity.sandbox_api_schema["financialInstitution"]["financialInstitutionAccount"]["financialInstitutionTransactions"]
36
+ .gsub("{financialInstitutionId}", financial_institution_id)
37
+ .gsub("{financialInstitutionUserId}", financial_institution_user_id)
38
+ .gsub("{financialInstitutionAccountId}", financial_institution_account_id)
39
+ .gsub("{financialInstitutionTransactionId}", id)
40
+ uri = Ibanity.client.build_uri(path)
41
+ update_by_uri(uri: uri, resource_type: "financialInstitutionTransaction", attributes: attributes, idempotency_key: idempotency_key)
42
+ end
43
+
34
44
  def self.delete(id:, financial_institution_user_id:, financial_institution_id:, financial_institution_account_id:)
35
45
  path = Ibanity.sandbox_api_schema["financialInstitution"]["financialInstitutionAccount"]["financialInstitutionTransactions"]
36
46
  .gsub("{financialInstitutionId}", financial_institution_id)
@@ -0,0 +1,10 @@
1
+ module Ibanity
2
+ module Xs2a
3
+ class FinancialInstitutionCountry < Ibanity::BaseResource
4
+ def self.list(**query_params)
5
+ uri = Ibanity.xs2a_api_schema["financialInstitutionCountries"]
6
+ list_by_uri(uri: uri, query_params: query_params)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,11 +1,16 @@
1
1
  module Ibanity
2
2
  module Xs2a
3
3
  class Transaction < Ibanity::BaseResource
4
- def self.list(financial_institution_id:, account_id:, customer_access_token:, headers: nil, **query_params)
5
- uri = Ibanity.xs2a_api_schema["customer"]["financialInstitution"]["transactions"]
6
- .sub("{financialInstitutionId}", financial_institution_id)
7
- .sub("{accountId}", account_id)
8
- .sub("{transactionId}", "")
4
+ def self.list(financial_institution_id: nil, account_id: nil, synchronization_id: nil, customer_access_token:, headers: nil, **query_params)
5
+ uri = if synchronization_id
6
+ Ibanity.xs2a_api_schema["customer"]["synchronization"]["updatedTransactions"]
7
+ .sub("{synchronizationId}", synchronization_id)
8
+ else
9
+ Ibanity.xs2a_api_schema["customer"]["financialInstitution"]["transactions"]
10
+ .sub("{financialInstitutionId}", financial_institution_id)
11
+ .sub("{accountId}", account_id)
12
+ .sub("{transactionId}", "")
13
+ end
9
14
  list_by_uri(uri: uri, query_params: query_params, customer_access_token: customer_access_token, headers: headers)
10
15
  end
11
16
 
@@ -3,13 +3,30 @@ module Ibanity
3
3
 
4
4
  attr_reader :base_uri, :signature_certificate, :signature_key, :isabel_connect_client_id, :isabel_connect_client_secret, :ponto_connect_client_id, :ponto_connect_client_secret
5
5
 
6
- def initialize(certificate:, key:, key_passphrase:, signature_certificate: nil, signature_certificate_id: nil, signature_key: nil, signature_key_passphrase: nil, api_scheme: "https", api_host: "api.ibanity.com", api_port: "443", ssl_ca_file: nil, isabel_connect_client_id: "valid_client_id", isabel_connect_client_secret: "valid_client_secret", ponto_connect_client_id: nil, ponto_connect_client_secret: nil)
6
+ def initialize(
7
+ certificate:,
8
+ key:,
9
+ key_passphrase:,
10
+ signature_certificate: nil,
11
+ signature_certificate_id: nil,
12
+ signature_key: nil,
13
+ signature_key_passphrase: nil,
14
+ api_scheme: "https",
15
+ api_host: "api.ibanity.com",
16
+ api_port: "443",
17
+ ssl_ca_file: nil,
18
+ isabel_connect_client_id: "valid_client_id",
19
+ isabel_connect_client_secret: "valid_client_secret",
20
+ ponto_connect_client_id: nil,
21
+ ponto_connect_client_secret: nil,
22
+ debug_http_requests: false)
7
23
  @isabel_connect_client_id = isabel_connect_client_id
8
24
  @isabel_connect_client_secret = isabel_connect_client_secret
9
25
  @ponto_connect_client_id = ponto_connect_client_id
10
26
  @ponto_connect_client_secret = ponto_connect_client_secret
11
27
  @certificate = OpenSSL::X509::Certificate.new(certificate)
12
28
  @key = OpenSSL::PKey::RSA.new(key, key_passphrase)
29
+ @http_debug = debug_http_requests
13
30
  if signature_certificate
14
31
  @signature_certificate = OpenSSL::X509::Certificate.new(signature_certificate)
15
32
  @signature_certificate_id = signature_certificate_id
@@ -25,12 +42,12 @@ module Ibanity
25
42
  end
26
43
 
27
44
  def post(uri:, payload:, query_params: {}, customer_access_token: nil, idempotency_key: nil, json: true, headers: nil)
28
- headers = build_headers(customer_access_token: customer_access_token, idempotency_key: idempotency_key, extra_headers: headers, json: json)
45
+ headers = build_headers(customer_access_token: customer_access_token, idempotency_key: idempotency_key, extra_headers: headers, json: json, payload: payload)
29
46
  execute(method: :post, uri: uri, headers: headers, query_params: query_params, payload: payload, json: json)
30
47
  end
31
48
 
32
49
  def patch(uri:, payload:, query_params: {}, customer_access_token: nil, idempotency_key: nil, json: true)
33
- headers = build_headers(customer_access_token: customer_access_token, idempotency_key: idempotency_key, json: json)
50
+ headers = build_headers(customer_access_token: customer_access_token, idempotency_key: idempotency_key, json: json, payload: payload)
34
51
  execute(method: :patch, uri: uri, headers: headers, query_params: query_params, payload: payload, json: json)
35
52
  end
36
53
 
@@ -46,6 +63,15 @@ module Ibanity
46
63
  private
47
64
 
48
65
  def execute(method:, uri:, headers:, query_params: {}, payload: nil, json:)
66
+ case payload
67
+ when NilClass
68
+ payload = ''
69
+ when Hash
70
+ payload = json ? payload.to_json : payload
71
+ when Pathname
72
+ payload = File.open(payload, 'rb')
73
+ end
74
+
49
75
  if @signature_certificate
50
76
  signature = Ibanity::HttpSignature.new(
51
77
  certificate: @signature_certificate,
@@ -55,23 +81,30 @@ module Ibanity
55
81
  uri: uri,
56
82
  query_params: query_params,
57
83
  headers: headers,
58
- payload: payload && json ? payload.to_json : payload
84
+ payload: payload
59
85
  )
60
86
  headers.merge!(signature.signature_headers)
61
87
  end
88
+
62
89
  query = {
63
90
  method: method,
64
91
  url: uri,
65
92
  headers: headers.merge(params: query_params),
66
- payload: payload && json ? payload.to_json : payload,
93
+ payload: payload,
67
94
  ssl_client_cert: @certificate,
68
95
  ssl_client_key: @key,
69
96
  ssl_ca_file: @ssl_ca_file
70
97
  }
98
+
99
+ log("HTTP Request", query) if @http_debug
100
+
71
101
  raw_response = RestClient::Request.execute(query) do |response, request, result, &block|
102
+ log("HTTP response", { status: response.code, headers: response.headers, body: response.body }) if @http_debug
103
+
72
104
  if response.code >= 400
73
105
  ibanity_request_id = response.headers[:ibanity_request_id]
74
106
  body = JSON.parse(response.body)
107
+
75
108
  raise Ibanity::Error.new(body["errors"] || body, ibanity_request_id), "Ibanity request failed."
76
109
  else
77
110
  response.return!(&block)
@@ -80,12 +113,15 @@ module Ibanity
80
113
  JSON.parse(raw_response)
81
114
  rescue JSON::ParserError => e
82
115
  return raw_response.body
116
+ ensure
117
+ payload.close if payload.is_a?(File)
83
118
  end
84
119
 
85
- def build_headers(customer_access_token: nil, idempotency_key: nil, extra_headers: nil, json:)
120
+ def build_headers(customer_access_token: nil, idempotency_key: nil, extra_headers: nil, json:, payload: nil)
86
121
  headers = {
87
122
  accept: :json,
88
123
  }
124
+ headers["Transfer-Encoding"] = "chunked" if payload.is_a?(Pathname)
89
125
  headers[:content_type] = :json if json
90
126
  headers["Authorization"] = "Bearer #{customer_access_token}" unless customer_access_token.nil?
91
127
  headers["Ibanity-Idempotency-Key"] = idempotency_key unless idempotency_key.nil?
@@ -95,5 +131,38 @@ module Ibanity
95
131
  headers.merge(extra_headers)
96
132
  end
97
133
  end
134
+
135
+ def log(tag, info)
136
+ unless info.is_a?(Hash)
137
+ puts "[DEBUG] #{tag}: #{info}"
138
+ return
139
+ end
140
+
141
+ info = JSON.parse(info.to_json)
142
+
143
+ if info.dig("headers", "Authorization")
144
+ info["headers"]["Authorization"] = "[filtered]"
145
+ end
146
+ info.delete("proxy")
147
+ info.delete("ssl_client_cert")
148
+ info.delete("ssl_client_key")
149
+ if info.dig("payload").is_a?(Hash) && info.dig("payload", "client_secret")
150
+ info["payload"]["client_secret"] = "[filtered]"
151
+ end
152
+
153
+ if info["body"]&.is_a?(String)
154
+ begin
155
+ info["body"] = JSON.parse(info["body"])
156
+ rescue => exception
157
+ info["body"] = Base64.strict_encode64(info["body"])
158
+ end
159
+ end
160
+
161
+ begin
162
+ puts "[DEBUG] #{tag}: #{info.to_json}"
163
+ rescue => e
164
+ puts "[DEBUG] #{tag}: #{info}"
165
+ end
166
+ end
98
167
  end
99
168
  end
@@ -1,6 +1,10 @@
1
1
  module Ibanity
2
2
  class Collection < DelegateClass(Array)
3
3
  attr_accessor :page_limit,
4
+ :page_number,
5
+ :page_size,
6
+ :total_entries,
7
+ :total_pages,
4
8
  :before_cursor,
5
9
  :after_cursor,
6
10
  :offset,
@@ -8,6 +12,7 @@ module Ibanity
8
12
  :first_link,
9
13
  :next_link,
10
14
  :previous_link,
15
+ :last_link,
11
16
  :latest_synchronization,
12
17
  :synchronized_at
13
18
 
@@ -23,6 +28,10 @@ module Ibanity
23
28
  links ||= {}
24
29
  @klass = klass
25
30
  @page_limit = paging["limit"]
31
+ @page_number = paging["pageNumber"]
32
+ @page_size = paging["pageSize"]
33
+ @total_entries = paging["totalEntries"]
34
+ @total_pages = paging["totalPages"]
26
35
  @before_cursor = paging["before"]
27
36
  @after_cursor = paging["after"]
28
37
  @offset = paging["offset"]
@@ -30,6 +39,7 @@ module Ibanity
30
39
  @first_link = links["first"]
31
40
  @next_link = links["next"]
32
41
  @previous_link = links["prev"]
42
+ @last_link = links["last"]
33
43
  @synchronized_at = synchronized_at
34
44
  @latest_synchronization = latest_synchronization
35
45
  super(items)
@@ -1,4 +1,5 @@
1
1
  require "base64"
2
+ require "pathname"
2
3
 
3
4
  module Ibanity
4
5
  class HttpSignature
@@ -29,16 +30,38 @@ module Ibanity
29
30
  }
30
31
  end
31
32
 
32
- private
33
-
34
33
  def payload_digest
35
- digest = OpenSSL::Digest::SHA512.new
36
- string_payload = @payload.nil? ? "" : @payload
37
- digest.update(string_payload)
34
+ @payload_digest ||= compute_digest
35
+ end
36
+
37
+ def compute_digest
38
+ case @payload
39
+ when NilClass
40
+ digest = compute_digest_string("")
41
+ when String
42
+ digest = compute_digest_string(@payload)
43
+ when File
44
+ digest = compute_digest_file(@payload)
45
+ end
38
46
  base64 = Base64.urlsafe_encode64(digest.digest)
39
47
  "SHA-512=#{base64}"
40
48
  end
41
49
 
50
+ def compute_digest_string(str)
51
+ digest = OpenSSL::Digest::SHA512.new
52
+ digest.update(str)
53
+ end
54
+
55
+ def compute_digest_file(pathname)
56
+ digest = OpenSSL::Digest::SHA512.new
57
+ File.open(pathname, 'rb') do |f|
58
+ while buffer = f.read(256_000)
59
+ digest << buffer
60
+ end
61
+ end
62
+ digest
63
+ end
64
+
42
65
  def headers_to_sign
43
66
  result = ["(request-target)", "host", "digest", "(created)"]
44
67
  result << "authorization" unless @headers["Authorization"].nil?
@@ -1,3 +1,3 @@
1
1
  module Ibanity
2
- VERSION = "1.5.0"
2
+ VERSION = "1.9.1"
3
3
  end
data/lib/ibanity.rb CHANGED
@@ -15,6 +15,7 @@ require_relative "ibanity/api/xs2a/account"
15
15
  require_relative "ibanity/api/xs2a/transaction"
16
16
  require_relative "ibanity/api/xs2a/holding"
17
17
  require_relative "ibanity/api/xs2a/financial_institution"
18
+ require_relative "ibanity/api/xs2a/financial_institution_country"
18
19
  require_relative "ibanity/api/xs2a/account_information_access_request"
19
20
  require_relative "ibanity/api/xs2a/account_information_access_request_authorization"
20
21
  require_relative "ibanity/api/xs2a/payment_initiation_request_authorization"
@@ -32,6 +33,7 @@ require_relative "ibanity/api/isabel_connect/intraday_transaction"
32
33
  require_relative "ibanity/api/isabel_connect/account_report"
33
34
  require_relative "ibanity/api/isabel_connect/access_token"
34
35
  require_relative "ibanity/api/isabel_connect/refresh_token"
36
+ require_relative "ibanity/api/isabel_connect/token"
35
37
  require_relative "ibanity/api/isabel_connect/bulk_payment_initiation_request"
36
38
  require_relative "ibanity/api/sandbox/financial_institution_account"
37
39
  require_relative "ibanity/api/sandbox/financial_institution_transaction"
@@ -45,16 +47,20 @@ require_relative "ibanity/api/ponto_connect/synchronization"
45
47
  require_relative "ibanity/api/consent/consent"
46
48
  require_relative "ibanity/api/consent/processing_operation"
47
49
  require_relative "ibanity/api/ponto_connect/payment"
50
+ require_relative "ibanity/api/ponto_connect/bulk_payment"
48
51
  require_relative "ibanity/api/ponto_connect/user_info"
49
52
  require_relative "ibanity/api/ponto_connect/usage"
53
+ require_relative "ibanity/api/ponto_connect/integration"
50
54
  require_relative "ibanity/api/ponto_connect/sandbox/financial_institution_account"
51
55
  require_relative "ibanity/api/ponto_connect/sandbox/financial_institution_transaction"
56
+ require_relative "ibanity/api/ponto_connect/onboarding_details"
57
+ require_relative "ibanity/api/ponto_connect/reauthorization_request"
52
58
 
53
59
  module Ibanity
54
60
  class << self
55
61
  def client
56
62
  options = configuration.to_h.delete_if { |_, v| v.nil? }
57
- @client ||= Ibanity::Client.new(options)
63
+ @client ||= Ibanity::Client.new(**options)
58
64
  end
59
65
 
60
66
  def configure
@@ -84,7 +90,8 @@ module Ibanity
84
90
  :api_scheme,
85
91
  :api_host,
86
92
  :api_port,
87
- :ssl_ca_file
93
+ :ssl_ca_file,
94
+ :debug_http_requests
88
95
  ).new
89
96
  end
90
97
 
@@ -0,0 +1,42 @@
1
+ require "ibanity"
2
+
3
+ class Ibanity::Xs2a::Car < Ibanity::BaseResource; end
4
+ class Ibanity::Xs2a::Manufacturer < Ibanity::BaseResource; end
5
+
6
+ RSpec.describe Ibanity::BaseResource do
7
+ describe "#relationship_klass" do
8
+ context "when 'data' attribute is present" do
9
+ it "retrieves the resource name from the 'type' attribute if it is present" do
10
+ car = Ibanity::Xs2a::Car.new(Fixture.load_json("relationships/data_with_type.json"))
11
+
12
+ expect(car).to respond_to(:maker)
13
+ end
14
+
15
+ it "falls back to the element name otherwise" do
16
+ car = Ibanity::Xs2a::Car.new(Fixture.load_json("relationships/data_without_type.json"))
17
+
18
+ expect(car).to respond_to(:manufacturer)
19
+ end
20
+ end
21
+
22
+ context "when the 'links' attribute is present" do
23
+ it "retrieves the resource name from the 'type' attribute within the 'links' attribute" do
24
+ car = Ibanity::Xs2a::Car.new(Fixture.load_json("relationships/meta_with_type.json"))
25
+
26
+ expect(car).to respond_to(:manufacturer)
27
+ end
28
+ end
29
+
30
+ context "when there's no 'links/related' element" do
31
+ let(:car) { Ibanity::Xs2a::Car.new(Fixture.load_json("relationships/no_links_related.json")) }
32
+
33
+ it "sets up a '<relationship_key>_id' property when there is a 'data/id' element" do
34
+ expect(car.manufacturer_id).to eq("6680437c")
35
+ end
36
+
37
+ it "discards the relationship" do
38
+ expect(car).not_to respond_to(:manufacturer)
39
+ end
40
+ end
41
+ end
42
+ end
data/spec/spec_helper.rb CHANGED
@@ -12,10 +12,16 @@
12
12
  # the additional setup, and require it from the spec files that actually need
13
13
  # it.
14
14
  #
15
+
16
+ Pathname.glob(Pathname.pwd().join("spec", "support", "**/*.rb")).each do |f|
17
+ require f
18
+ end
19
+
15
20
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
21
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
17
22
 
18
23
  RSpec.configure do |config|
24
+ config.include(Fixture)
19
25
  # rspec-expectations config goes here. You can use an alternate
20
26
  # assertion/expectation library such as wrong or the stdlib/minitest
21
27
  # assertions if you prefer.
@@ -0,0 +1,8 @@
1
+ require "json"
2
+
3
+ module Fixture
4
+ def self.load_json(filename)
5
+ path = Pathname([File.dirname(__FILE__ ), "fixtures", "json", filename].join("/"))
6
+ JSON.parse(File.read(path))
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ {
2
+ "attributes": {
3
+ "color": "blue"
4
+ },
5
+ "id": "62ebd4687e",
6
+ "links": {
7
+ "self": "https://www.cardb.com/models/62ebd4687e"
8
+ },
9
+ "relationships": {
10
+ "maker": {
11
+ "data": {
12
+ "id": "c4ebf0f7",
13
+ "type": "manufacturer"
14
+ },
15
+ "links": {
16
+ "related": "https://www.cardb.com/manufacturers/c4ebf0f7"
17
+ }
18
+ }
19
+ },
20
+ "type": "car"
21
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "attributes": {
3
+ "color": "blue"
4
+ },
5
+ "id": "62ebd4687e",
6
+ "links": {
7
+ "self": "https://www.cardb.com/models/62ebd4687e"
8
+ },
9
+ "relationships": {
10
+ "manufacturer": {
11
+ "data": {
12
+ "id": "c4ebf0f7"
13
+ },
14
+ "links": {
15
+ "related": "https://www.cardb.com/manufacturers/c4ebf0f7"
16
+ }
17
+ }
18
+ },
19
+ "type": "car"
20
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "attributes": {
3
+ "color": "blue"
4
+ },
5
+ "id": "62ebd4687e",
6
+ "links": {
7
+ "self": "https://www.cardb.com/models/62ebd4687e"
8
+ },
9
+ "relationships": {
10
+ "manufacturer": {
11
+ "links": {
12
+ "related": "https://www.cardb.com/manufacturers/c4ebf0f7"
13
+ },
14
+ "meta": {
15
+ "type": "manufacturer"
16
+ }
17
+ }
18
+ },
19
+ "type": "car"
20
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "id": "62ebd4687e",
3
+ "attributes": {
4
+ "color": "blue"
5
+ },
6
+ "relationships": {
7
+ "manufacturer": {
8
+ "data": {
9
+ "type": "manufacturer",
10
+ "id": "6680437c"
11
+ }
12
+ }
13
+ },
14
+ "type": "car"
15
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ibanity
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ibanity
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-21 00:00:00.000000000 Z
11
+ date: 2021-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -45,10 +45,11 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/workflows/ci.yml"
49
+ - ".github/workflows/gem-push.yml"
48
50
  - ".gitignore"
49
51
  - ".gitkeep"
50
52
  - ".rspec"
51
- - ".travis.yml"
52
53
  - CHANGELOG.md
53
54
  - Gemfile
54
55
  - LICENSE.txt
@@ -66,11 +67,16 @@ files:
66
67
  - lib/ibanity/api/isabel_connect/bulk_payment_initiation_request.rb
67
68
  - lib/ibanity/api/isabel_connect/intraday_transaction.rb
68
69
  - lib/ibanity/api/isabel_connect/refresh_token.rb
70
+ - lib/ibanity/api/isabel_connect/token.rb
69
71
  - lib/ibanity/api/isabel_connect/transaction.rb
70
72
  - lib/ibanity/api/o_auth_resource.rb
71
73
  - lib/ibanity/api/ponto_connect/account.rb
74
+ - lib/ibanity/api/ponto_connect/bulk_payment.rb
72
75
  - lib/ibanity/api/ponto_connect/financial_institution.rb
76
+ - lib/ibanity/api/ponto_connect/integration.rb
77
+ - lib/ibanity/api/ponto_connect/onboarding_details.rb
73
78
  - lib/ibanity/api/ponto_connect/payment.rb
79
+ - lib/ibanity/api/ponto_connect/reauthorization_request.rb
74
80
  - lib/ibanity/api/ponto_connect/sandbox/financial_institution_account.rb
75
81
  - lib/ibanity/api/ponto_connect/sandbox/financial_institution_transaction.rb
76
82
  - lib/ibanity/api/ponto_connect/synchronization.rb
@@ -89,6 +95,7 @@ files:
89
95
  - lib/ibanity/api/xs2a/customer.rb
90
96
  - lib/ibanity/api/xs2a/customer_access_token.rb
91
97
  - lib/ibanity/api/xs2a/financial_institution.rb
98
+ - lib/ibanity/api/xs2a/financial_institution_country.rb
92
99
  - lib/ibanity/api/xs2a/holding.rb
93
100
  - lib/ibanity/api/xs2a/payment_initiation_request.rb
94
101
  - lib/ibanity/api/xs2a/payment_initiation_request_authorization.rb
@@ -101,10 +108,16 @@ files:
101
108
  - lib/ibanity/http_signature.rb
102
109
  - lib/ibanity/util.rb
103
110
  - lib/ibanity/version.rb
111
+ - spec/lib/ibanity/base_resource_spec.rb
104
112
  - spec/lib/ibanity/http_signature_spec.rb
105
113
  - spec/lib/ibanity/util_spec.rb
106
114
  - spec/spec_helper.rb
107
115
  - spec/support/crypto_helper.rb
116
+ - spec/support/fixture.rb
117
+ - spec/support/fixtures/json/relationships/data_with_type.json
118
+ - spec/support/fixtures/json/relationships/data_without_type.json
119
+ - spec/support/fixtures/json/relationships/meta_with_type.json
120
+ - spec/support/fixtures/json/relationships/no_links_related.json
108
121
  - spec/support/fixtures/signature/test-certificate.pem
109
122
  - spec/support/fixtures/signature/test-private_key.pem
110
123
  - spec/support/fixtures/signature/test-public_key.pem
@@ -127,15 +140,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
140
  - !ruby/object:Gem::Version
128
141
  version: '0'
129
142
  requirements: []
130
- rubygems_version: 3.0.8
143
+ rubygems_version: 3.0.3.1
131
144
  signing_key:
132
145
  specification_version: 4
133
146
  summary: Ibanity Ruby Client
134
147
  test_files:
148
+ - spec/lib/ibanity/base_resource_spec.rb
135
149
  - spec/lib/ibanity/http_signature_spec.rb
136
150
  - spec/lib/ibanity/util_spec.rb
137
151
  - spec/spec_helper.rb
138
152
  - spec/support/crypto_helper.rb
153
+ - spec/support/fixture.rb
154
+ - spec/support/fixtures/json/relationships/data_with_type.json
155
+ - spec/support/fixtures/json/relationships/data_without_type.json
156
+ - spec/support/fixtures/json/relationships/meta_with_type.json
157
+ - spec/support/fixtures/json/relationships/no_links_related.json
139
158
  - spec/support/fixtures/signature/test-certificate.pem
140
159
  - spec/support/fixtures/signature/test-private_key.pem
141
160
  - spec/support/fixtures/signature/test-public_key.pem
data/.travis.yml DELETED
@@ -1,20 +0,0 @@
1
- language: ruby
2
- script: bundle exec rspec
3
- deploy:
4
- provider: rubygems
5
- api_key:
6
- secure: pfXgGXH/AZEG3HMiaJPmJ7fck6Z3Hj0y7TU5TwvLAtKuBy6hlLT67ne/VfeBZQKa9d7eerr9PFP1hvLjZppScZMMOTtjBTvwpchkcUDwCxHx5GzS/jRnBF+uYHIza2p4Wq8yIPug7UrZ0qyq5VOG45R/nC/fPm2Ht2T7heqF5VgRaDGrN7Fq3zXn7duiYhTy02nDXorZ/kEAjnwdwDtXWyVFq8wr4inTExYrDP9/M57qx5TrkgWmcQ7JrvO2KfLDMJqAxI8lNoaPl5dAi7q1XWqqSVay7h9OAnP4UfvnvAc106lG6nHfTQig1krTfxRAvtHlPQjSlFkL+0qfBPBz1C/ex221O3NsNBYmI/mJ45lcNhqJbnkV2VEAEgUoe4ZFfKUUczLfnVxIPjoQmHMwLwfEO4g8/Hz/I3L7bvebgfzGGMDpmN6ERZRJmhutE6K5cL80ghoLs6ExJLoqHi1qvdBSkM2IyE4Yo+lob/hKU1IBL1w13T2h3EHapBh3kKn+jBzu/y5nXTEteBHbMP8j2zxFiihVBJEKPXhg/iU8WHLI6HZgWJkOc9ZH3hS7CN3VELK7fVZp9jaPAKaKihdvxQ0z3gCPFL+E6rYKsBPYqXE6qDsSQswhqTN15W0eVQqK8fDXkZmW0lSGvi2IJvL0CjIaahfB2GaapTtqOwar7sc=
7
- on:
8
- tags: true
9
- gem: ibanity
10
- skip_cleanup: true
11
- notifications:
12
- email: false
13
- slack:
14
- - rooms:
15
- - secure: J06CK+muuVTW1SS1GmhSw7ZVo0vEMFpNWU5B9Cz94h5BZI3rPSxZFSCQG8OTQ/lBIrzPTlQj5JGzYgHpS5QRHGa4s1A1tYrZUfjUUgaZ7SIfoY8AgHH6cKF+jtwYy2z+kOJekBtfNLqfzAx+48QrxdbmBnXTG+r7UXczw0TAB7BMKh8107q7kqgjKiAnpGlXzC6rLWUwdRF/1qvDtYFCjoZ0OpYMnUUK+0/bgwVHxjYRl64DrPD3jC2XoaCTRCMyLbfqb9ZUXKVf27ByAQ/Ikj+qODdSH10vwPARXlbbVhpPfjAax42zC1OwSABdE00iJW1+TuoI69znjWg1d8Ti97raihV98OXMyqHXPKxX/gZp+0MSuYIE9GQWY791ulmQ+GwwkgB6v2LmXGCE8K+eUCc3zkGJWVUzBP+Wu49mDzDAQHBPl/G3u26RqmVQzWhk9ckHQ30cyIPFjz/eaMrda+wgQ6AKzfNq+XVL6hAO+Se28PRPhDu33ZzIKqgpk0dH77LcKPI/Uf1dCT+0oa+pvVx1T0Z93SNp0azh71rx9AOWBMZm7TcOYvMOw9QpVBZkoWy4NQo9PMT0Jo73qAnOTHadr8b5zeDoAu7jnlhCxIpmnrmIh4Dz6n6XF+c+d+C/MAQVQ0rKj7KzTYEsYat0NQ62lgBtHy5/Qmu736MaIVA=
16
- if: (tag =~ ^v) AND (branch = master)
17
- - rooms:
18
- - secure: J06CK+muuVTW1SS1GmhSw7ZVo0vEMFpNWU5B9Cz94h5BZI3rPSxZFSCQG8OTQ/lBIrzPTlQj5JGzYgHpS5QRHGa4s1A1tYrZUfjUUgaZ7SIfoY8AgHH6cKF+jtwYy2z+kOJekBtfNLqfzAx+48QrxdbmBnXTG+r7UXczw0TAB7BMKh8107q7kqgjKiAnpGlXzC6rLWUwdRF/1qvDtYFCjoZ0OpYMnUUK+0/bgwVHxjYRl64DrPD3jC2XoaCTRCMyLbfqb9ZUXKVf27ByAQ/Ikj+qODdSH10vwPARXlbbVhpPfjAax42zC1OwSABdE00iJW1+TuoI69znjWg1d8Ti97raihV98OXMyqHXPKxX/gZp+0MSuYIE9GQWY791ulmQ+GwwkgB6v2LmXGCE8K+eUCc3zkGJWVUzBP+Wu49mDzDAQHBPl/G3u26RqmVQzWhk9ckHQ30cyIPFjz/eaMrda+wgQ6AKzfNq+XVL6hAO+Se28PRPhDu33ZzIKqgpk0dH77LcKPI/Uf1dCT+0oa+pvVx1T0Z93SNp0azh71rx9AOWBMZm7TcOYvMOw9QpVBZkoWy4NQo9PMT0Jo73qAnOTHadr8b5zeDoAu7jnlhCxIpmnrmIh4Dz6n6XF+c+d+C/MAQVQ0rKj7KzTYEsYat0NQ62lgBtHy5/Qmu736MaIVA=
19
- on_success: change
20
- on_failure: always