From 72f011e988ec501695fed5a5576e348b4353c1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Wed, 19 Jun 2024 11:17:00 +0200 Subject: [PATCH 01/16] DatapassWebhook::AdaptV2ToV1 affects all authorization request data Prepare to exploit modalities field for access --- app/interactors/datapass_webhook/adapt_v2_to_v1.rb | 1 + spec/organizers/datapass_webhook/v2/api_particulier_spec.rb | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/app/interactors/datapass_webhook/adapt_v2_to_v1.rb b/app/interactors/datapass_webhook/adapt_v2_to_v1.rb index 7a4dc7f91..d5d3139c8 100644 --- a/app/interactors/datapass_webhook/adapt_v2_to_v1.rb +++ b/app/interactors/datapass_webhook/adapt_v2_to_v1.rb @@ -1,6 +1,7 @@ class DatapassWebhook::AdaptV2ToV1 < ApplicationInteractor def call context.event = context.event.sub('authorization_request', 'enrollment') + context.authorization_request_data = generic_data.dup context.data = build_data end diff --git a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb index 6c857b030..65ba4311f 100644 --- a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb +++ b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb @@ -71,4 +71,8 @@ subject end end + + it 'affects authorization request data to authorization_request_data on context' do + expect(subject.authorization_request_data).to eq(datapass_webhook_params['data']['data']) + end end From ae1f82b0c5be9140fa624512222dc67bedbaa9d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Wed, 19 Jun 2024 11:33:29 +0200 Subject: [PATCH 02/16] API Particulier DataPass webhook : do not create token if there is no params modalities --- .../datapass_webhook/create_or_prolong_token.rb | 5 +++++ app/organizers/datapass_webhook/api_particulier.rb | 2 ++ spec/factories/datapass_webhooks_v2.rb | 4 ++++ .../datapass_webhook/v2/api_particulier_spec.rb | 12 ++++++++++++ 4 files changed, 23 insertions(+) diff --git a/app/interactors/datapass_webhook/create_or_prolong_token.rb b/app/interactors/datapass_webhook/create_or_prolong_token.rb index cf67e2202..d1c7530cc 100644 --- a/app/interactors/datapass_webhook/create_or_prolong_token.rb +++ b/app/interactors/datapass_webhook/create_or_prolong_token.rb @@ -1,6 +1,11 @@ class DatapassWebhook::CreateOrProlongToken < ApplicationInteractor + before do + context.modalities ||= %w[params] + end + def call return if %w[approve validate].exclude?(context.event) + return if context.modalities.exclude?('params') token = create_or_prolong_token diff --git a/app/organizers/datapass_webhook/api_particulier.rb b/app/organizers/datapass_webhook/api_particulier.rb index b6076ebc1..0604b187d 100644 --- a/app/organizers/datapass_webhook/api_particulier.rb +++ b/app/organizers/datapass_webhook/api_particulier.rb @@ -8,6 +8,8 @@ class APIParticulier < ApplicationOrganizer } context.api = 'particulier' + context.authorization_request_data ||= {} + context.modalities = context.authorization_request_data['modalities'].presence || %w[params] end organize ::DatapassWebhook::FindOrCreateUser, diff --git a/spec/factories/datapass_webhooks_v2.rb b/spec/factories/datapass_webhooks_v2.rb index 323b5dddd..6360112b0 100644 --- a/spec/factories/datapass_webhooks_v2.rb +++ b/spec/factories/datapass_webhooks_v2.rb @@ -60,5 +60,9 @@ contact_metier_given_name { 'Jacques' } contact_metier_family_name { 'Metier' } contact_metier_job_title { 'CMO' } + + modalities do + %w[params] + end end end diff --git a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb index 65ba4311f..ecc0e8d44 100644 --- a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb +++ b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb @@ -41,6 +41,18 @@ expect(last_token.api).to eq('particulier') end + context 'when modalities does no include params' do + before do + datapass_webhook_params['data']['data']['modalities'] = ['formulaire_qf'] + end + + it 'does not create a token' do + expect { + subject + }.not_to change(Token, :count) + end + end + describe 'Mailjet adding contacts' do it 'adds contacts to Entreprise mailjet list' do expect(Mailjet::Contactslist_managemanycontacts).to receive(:create).with( From aa69423355221c254770fab38f50ab156db3a6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Wed, 19 Jun 2024 11:42:16 +0200 Subject: [PATCH 03/16] HubEE is an acronym Ignore specs file path name, does not handle well and not an issue. --- .rubocop.yml | 4 ++++ config/initializers/inflections.rb | 2 ++ 2 files changed, 6 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 41ffc3e03..fad8c07b2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -93,6 +93,10 @@ Metrics/MethodLength: RSpec/NestedGroups: Enabled: false +RSpec/SpecFilePathFormat: + Exclude: + - "spec/**/*hubee*" + Naming/VariableNumber: Enabled: false diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 6cc7380eb..cd9d628eb 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -15,4 +15,6 @@ inflect.acronym 'HTTP' inflect.acronym 'FAQ' + + inflect.acronym 'HubEE' end From 8e08829bb2a77fc7dc848a31dab2f93c74f13205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Wed, 19 Jun 2024 12:04:11 +0200 Subject: [PATCH 04/16] INSEE is an acronym --- config/initializers/inflections.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index cd9d628eb..8b31f8036 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -17,4 +17,5 @@ inflect.acronym 'FAQ' inflect.acronym 'HubEE' + inflect.acronym 'INSEE' end From d2961331071747d4d5491b4d270990dfe280ee19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Fri, 21 Jun 2024 16:33:36 +0200 Subject: [PATCH 05/16] QF is an acronym --- config/initializers/inflections.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 8b31f8036..cac5b73cd 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -18,4 +18,6 @@ inflect.acronym 'HubEE' inflect.acronym 'INSEE' + + inflect.acronym 'QF' end From 15e8843b3f2175fe7842eff7a6d2f98e155cf78e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Mon, 24 Jun 2024 17:28:13 +0200 Subject: [PATCH 06/16] Add extra_infos to authorization requests Prepare to store HubEE ids --- ...240624152759_add_extra_infos_to_authorization_requests.rb | 5 +++++ db/schema.rb | 1 + 2 files changed, 6 insertions(+) create mode 100644 db/migrate/20240624152759_add_extra_infos_to_authorization_requests.rb diff --git a/db/migrate/20240624152759_add_extra_infos_to_authorization_requests.rb b/db/migrate/20240624152759_add_extra_infos_to_authorization_requests.rb new file mode 100644 index 000000000..3db463e21 --- /dev/null +++ b/db/migrate/20240624152759_add_extra_infos_to_authorization_requests.rb @@ -0,0 +1,5 @@ +class AddExtraInfosToAuthorizationRequests < ActiveRecord::Migration[7.1] + def change + add_column :authorization_requests, :extra_infos, :jsonb, default: {} + end +end diff --git a/db/schema.rb b/db/schema.rb index 9e3385e3b..a5141ef0d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -34,6 +34,7 @@ t.string "siret" t.string "api", null: false t.string "demarche" + t.jsonb "extra_infos", default: {} t.uuid "public_id" t.index ["external_id"], name: "index_authorization_requests_on_external_id", unique: true, where: "(external_id IS NOT NULL)" end From 6f1dbd8d5c71ab77bb32153465d1b84822fa5b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Wed, 19 Jun 2024 12:10:54 +0200 Subject: [PATCH 07/16] Introduce INSEESireneAPIClient Huge cherry-pick from DataPass v2 Ref https://github.com/etalab/data_pass/commit/7c36324b50c1cef85c7e840c583bed6ae8ef89f0 --- Gemfile | 3 + Gemfile.lock | 5 + app/clients/abstract_insee_api_client.rb | 23 +++++ app/clients/insee_api_authentication.rb | 19 ++++ app/clients/insee_sirene_api_client.rb | 15 +++ config/credentials/production.yml.enc | 2 +- config/credentials/sandbox.yml.enc | 2 +- config/credentials/staging.yml.enc | 2 +- config/credentials/test.yml.enc | 2 +- spec/clients/insee_sirene_api_client_spec.rb | 43 ++++++++ spec/fixtures/insee/13002526500013.json | 102 +++++++++++++++++++ spec/rails_helper.rb | 2 + spec/support/fixtures_helpers.rb | 17 ++++ spec/support/insee_sirene_api_mocks.rb | 28 +++++ 14 files changed, 261 insertions(+), 4 deletions(-) create mode 100644 app/clients/abstract_insee_api_client.rb create mode 100644 app/clients/insee_api_authentication.rb create mode 100644 app/clients/insee_sirene_api_client.rb create mode 100644 spec/clients/insee_sirene_api_client_spec.rb create mode 100644 spec/fixtures/insee/13002526500013.json create mode 100644 spec/support/fixtures_helpers.rb create mode 100644 spec/support/insee_sirene_api_mocks.rb diff --git a/Gemfile b/Gemfile index 40f3e3fa9..9b973cc9f 100644 --- a/Gemfile +++ b/Gemfile @@ -77,6 +77,9 @@ gem 'ransack' gem 'wicked' gem 'rest-client' +gem 'faraday' +gem 'faraday-net_http' +gem 'faraday-retry' group :development, :test do gem 'awesome_print' diff --git a/Gemfile.lock b/Gemfile.lock index 9a8ea916d..0b6d5c2f5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -162,6 +162,8 @@ GEM faraday-net_http_persistent (2.3.0) faraday (~> 2.5) net-http-persistent (>= 4.0.4, < 5) + faraday-retry (2.2.1) + faraday (~> 2.0) ferrum (0.15) addressable (~> 2.5) concurrent-ruby (~> 1.1) @@ -585,6 +587,9 @@ DEPENDENCIES cuprite draper factory_bot_rails + faraday + faraday-net_http + faraday-retry gaffe good_job (~> 3.99) guard-rspec diff --git a/app/clients/abstract_insee_api_client.rb b/app/clients/abstract_insee_api_client.rb new file mode 100644 index 000000000..5b836e6fa --- /dev/null +++ b/app/clients/abstract_insee_api_client.rb @@ -0,0 +1,23 @@ +require 'faraday' + +class AbstractINSEEAPIClient + protected + + def http_connection(&block) + @http_connection ||= Faraday.new do |conn| + conn.request :retry, max: 5 + conn.response :raise_error + conn.response :json + conn.options.timeout = 2 + yield(conn) if block + end + end + + def consumer_key + Rails.application.credentials.insee_consumer_key + end + + def consumer_secret + Rails.application.credentials.insee_consumer_secret + end +end diff --git a/app/clients/insee_api_authentication.rb b/app/clients/insee_api_authentication.rb new file mode 100644 index 000000000..85154071c --- /dev/null +++ b/app/clients/insee_api_authentication.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class INSEEAPIAuthentication < AbstractINSEEAPIClient + def access_token + http_connection.post( + 'https://api.insee.fr/token', + 'grant_type=client_credentials', + { + 'Authorization' => "Basic #{encoded_client_id_and_secret}" + } + ).body['access_token'] + end + + private + + def encoded_client_id_and_secret + Base64.strict_encode64("#{consumer_key}:#{consumer_secret}") + end +end diff --git a/app/clients/insee_sirene_api_client.rb b/app/clients/insee_sirene_api_client.rb new file mode 100644 index 000000000..488ca977f --- /dev/null +++ b/app/clients/insee_sirene_api_client.rb @@ -0,0 +1,15 @@ +class INSEESireneAPIClient < AbstractINSEEAPIClient + def etablissement(siret:) + http_connection.get( + "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{siret}" + ).body + end + + protected + + def http_connection + super do |conn| + conn.request :authorization, 'Bearer', -> { INSEEAPIAuthentication.new.access_token } + end + end +end diff --git a/config/credentials/production.yml.enc b/config/credentials/production.yml.enc index 876d33cf9..b0e07d3af 100644 --- a/config/credentials/production.yml.enc +++ b/config/credentials/production.yml.enc @@ -1 +1 @@ -tv7dkgECrEHO7XjFVI+uBHMKL+R7IMLx6Gu8uYD2JEp6FH1m9lq9L6AySYlAHV9VqZhkLEgtSX3s69y4c2/tssBu/xxGD8dFhUL1vx7ebYxEM5Wjz1Kv4wLF+YEgf8MziyPnQHCH1HsWwfa2JrF9SHCThkUhADeJOU+FU+TlDbnnAxMMRQm2OKQo9/1tUrhoK+gGHZD9zOuB1UdKe49n2TxZfbI7wss29n9L/vWaiyVE8DS4DWe9PZj9c0HjCdToUl0Do7PwQNHw7COW26cqmGxZ2lEq3SCwLlLpWFzSz8HJUhTdElVpf8oPm18aepQEqeTnO+wG+PFp9B6Ty/wWEM2qVAOBifudBm8Th3eeHPlYtP33IUF2up0fu6uQHv57M0kN6dBvMD82S4IyQIjI89TWq2Y4/XL2nYz3RhqBkavskfxT50fLhfsRS3I7FAjNT4MezKOP6dG+1xiJpAjO+Aji3vkK3R0h6s4NIC6UtRYhJbASoK0bDInh0T+FZ12KvsUeXpWaCOA6LNpKAoPHahRZWG85yqxfddtfDw2HLDQtYyYJ7NPT0whMT9g01XFZh7IRoTXNUHJhZfo2Nr9hGJlZn6jZ74x2ucE4Qd9oS4OI4bTv/ZTc6BuALSLU0RfqHsW8EbYZn8j1DFdtDHmRLBRhQ8pbTqIEHX2FI72FgM7I0a6Ba6vseC01tQwSsVkr1M3bhFUHMkGc28C7vK680T9J7oNhE6pQq8FqnPDuQuO+ZOjLiV+Meuo450EAqFuppCrfjR4xuIUh+jE6wr9lmtakYkFU8BrtC7v5FcrRNp1IT9bYcUl8NE8JtpKWqXfM46/e32b8yqRsK9aUd3UdPtXLDT/LxHlqn1R3j76+RSE89WQQBwqUTVjw23AZt3IKjN87P7SpBYY6caDAgRewv+2BS7BYngP0fYIBBpmg9jKX4TvvJuULiH+tU9+iIL6hLg7PNQRim7t9WusLDKb/cSCacB9tvE5wS8L7ohmUzjZAW1yx04DfWJA2ejvUhToAaQEBerPRIj5/GvonmuSL6XDGzDJzipMmHg4gYQ/PhJHghJzdIOFZhYhEobNbNYGYK1rOUkdHJbxu0EMlVqEt8PnVs1JJavkHx5ms2GgQ9aO3E+1Uz0BhN7oX9SxE7WU54BVQOWiEhEp6ctobDUJKYSy+mZMP3G7fa/+8JkmjKkxSaP+SG48O73AzkS/AnC6mHOK38JRyK1/Wcj1gi4MJGJEQ90FuRjKUdlABbk3Kyx0FznrRhrGrkqV2V5H+D7XgeG5SrCVXJFiysuPk40j1dXofoulBE4POi0GVvTQTmU+s0XmIIrEF2khbASQ3TmBfOM5VS2+A88wPCVRUrWWO5bTAMbpfd0EO9hOZz5uuOIo2JP7GkC83w5pSz/JRdsbd/Ra1FLpb4/GVk5X+1KRuIn50izxue9nN7i6P4/JgBiEDBBvKVC/WJXbjH6vbX2l6v8NCYJxSoj5AeRiAPKfta0lONPzMaBZCs8tyLGu1BHZ4LlTdUv4BfyyyBXvd21G52g6zATDX5oEb9nBoELgjhZLPTSyNcsbinQfLZ1BW+QHEUabqjgj+VZwGXKiWpzHNMdl06jy8QLUK+4AKgyB+oighsQoCq1JT0+prowqG/5Fim3HkDn80rN0MtWJXVT9cQP4ac73feJqP2UPG05WeudLIzO8V2cZAYbHvsrujE2XDx2Vpe1kz6AmnRfSQJj/VfBHMM1uUSv3EqiE9N/DdHXQTrciX0wXgWXOEEhCUsK5WmOGQAWfpEBZTkCHclrYOLkTa4Cb+zyXxGzmCI9RMmbWVpoK+OBjtrZmb9nmRo/LlhXRcWfga1IiLxAfqQN6CaXo1RrG8ph2GVGs+v5Z9BA78hz5Hbo/wUBv7NwkujEwz4XkDo/B0nbSJKOZzD9PJPRPNi1eNAg7sUCypH/7XXcuDCwlo064I+O3t9IxxBud7cXV11If+zVw/MYZy42Ucv77hyM19nBO8rddhGVUJj1oizzaIDJ8/lzEHXuRPre5RxqBKg2t3uhBcqwzIpvKYqwGtsklF/iQlKm6nDM+ZV1UgKz/F2kolQLHdoAf/sQSxsoPRl691r4kQXECcXeZqTP+3d1DnvNXTafBLf5Gvi9fB3VcaroDr80BbwpUrNbVTBLFm9JCO/yzDN0hvhchxk0V339DSOl/uL3tbK0qyOqiwl2hDwlcERxJZa+xdliam66Jn1WjUwrt49Ai5dKAEauQpIk40V91g1T/T/6RQDKnZzKO8prcug5NFLA/LgXzoYE/2pH+5O3PnD6C2rz1BxpsoYHetn2mjqzubsFPe9VX1AEBD2FlteZtGRFq64NByAowKqQwXUJ5RmwcN+JH/E/WZp6ZbZJES2tJwRf8eTpusU7ig1V0HkpBsqAMNQqYiCuLHBmttOPcOImEDHYCSLkxWgxrm47YMimhvtfQNmV1GPrDpvyap5FwfSqMHgmfQFR8tJla7L0I5PMt/DvQTtwIe9ch1pZ/EfYVnbQuCcJMqWowsXxutZAyhqUFU1X+sVUkmas6GY7wc3/yvxhSSpDiV18qebfUnsNQ4cnVapybVa0SgxOKx2WEHikcncJauGQcY2oW7ZugLE4mvOWNlV6GGodhj8vyyrfo1oYtUX9oXXhiFF0SZr+/ZpmDQYNoA9rpd+nCQbmzTy9BzdAYFDaHx51bJWdHZmXZ5reXwKPU39LmrEbZh5mU5rHpVGJQ1NgCt1mrMoCinJ0zUeuZFRzJbYcfiI3rzmaNVujwbzWXLc8tXf8i2cFiNerdRozpVXUxcKX8hdmxp3F7d/xK4OoSj8Nve7A4JMpnc640XX7gyGmoXwn1qZLhFEpexDlB6Sy7M57mzbGcYlpg/DkeOfMQP8CCU3GNLskQdgNntgznRrs2BSBLJ1AqbC2ZuclBA32sMwGVLPYkL5PzwD5YXiLdpIAGW6pYIm4Kl8WSptX0lWZ79i5LLdUn9gjd3X5LqPj4eh2TzEySiS46jBjE86L9pvEiCr3o0trZ52m49Lk+SoyQB/D/Rc5qT9JtfoI1qAaV10cVJAIuW0Ww5o21W+vGytOVjgBND1u3Ktvuf0gpUvm8oNOgy/OfrT1djXNqqEOd3q1ZWinxlKQpwfPQ63DHbVvZsOxUhsMAXFUJyKHisIakvYouBC6891k/6rhr6yNELjHYS+4dA2OTqai0+BPb0CDha47Mo8aHiSXngVai/r6fNl6AUhblPEKG7evi3y1jcNdRHWLyQBwnMYTgn+BLRJM49LNLLXdwXZP6PXRsyDtkf8oKuWKdJFTXv9m+NQJnMOBgUyX3WxvlOqd/p8VSCJlb8Yl3dqh2O/VrA1FMAXuPPYJKM81qBOjLbKG8+j2REGhSQbRNTLF2eBuY5aQUVdfZ9vN9C12pW6xp0fYP9S3I9GYHi8LLJg0QQpuq9F7Q8dB0OglrnYysqKCb7GtOHhxgILqhBvfWvIZ0N65o9tFDCUc2GDNlzK6URLCRWp4tLGZITv6c0i4onYM15GywV/rTyku7updCrjZcImCfeQvtE73vTpLKR86+I0ix2w2qbtx8tNZA78iW/AOixIeBUcVQ1S/cSHuGYQAKMc3mBwTe7FFCfIlfhwPKnXMeWMEBjaQ4o8YHf0i1IgiwHsKCTRT3B5WVCF/ENkuMfQflyf1nfOE4BLGbgXhzM49OnqRbEX8kDNO/clx1uNYQRC/1ruDM7+Y7HxYeMb1UCfWHStCWMBD0hOWdUiVloDPbj6QyJoq9OuDTcn1Y3xs6FU/VdPc2aZeyL2hnSXf+DQBH3sBArtB4y76oUqgFqtYrj9YZHiq7FOp1irDjWuZ6ITxbAAlhghZcFurlc9RQPs9z1zyfqkllAQPc0V600tM/OE8kEaVg0aV5jJA+XLe+OvFsp8DM4W8Nkrks1BSEd94r4wRtyxv+vDgejXqWO3HwdNEWpOXkhtSXzuxfAj5FkItj/HKaxDS6tKLVnNnz8g1VamEdREYCkHwjNg5WwXCQQkhW7Io/VN6jwyGOAuMvBP8U5CtEmR2Ej0OmxTagxgLv9fzQA/wuuYJWzDSdlPk3LPCWct6L4xkxP8+RqjD7HjxclcyPRKYTDi1eS3i7z9JkFEpO7r2hSUE9YyZEmwudgvYAKY/ZDNJGrpuOoMer7XSDS4TWwPQ0HEXcT4aJU9oKQ3Ce5H9QMhh+R3NhG8CZPymoVA0Si2jFCmwDTmMb/+7563a20STO6Qq/xCLpHLIDWQKjcS/VpA2n7GUETh+vcjX/yDxTJrcj5niE/i0Bcf2r8ibPDaLqBbB9UO1oL0YGMNw9/jBKS+SKs65c3UrYtlUwGVJGl9JcxSPZTjNKmw4acfQZ73QaxmfUq3gDofXdshq02xL1ATg==--h4gZdNZdw5pFYh0p--MeT3D9sz1WMJUcSe1jGZ4Q== \ No newline at end of file +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--tgGTVwo/lU3jhCuB--9N1N4TlMV/Rw+Vk07mxh/w== \ No newline at end of file diff --git a/config/credentials/sandbox.yml.enc b/config/credentials/sandbox.yml.enc index a9fa2cd98..d4a03a175 100644 --- a/config/credentials/sandbox.yml.enc +++ b/config/credentials/sandbox.yml.enc @@ -1 +1 @@ -WXXMzkxUMGPk9DyWjuIoBM7ei3Qxi1M3mgKXW0jpEmW3DD7SJ4CVm7VnfuerOq59nDBeugTdY34h6DWSXQQ+d/ZpgxDDBX/TASWj5tBYjjYu+g7bYGsvXwYnGNJd7xnAD8zCndBAhwfQn7TXnCzhCCytrNvLen61+scndaPRNv3ipIC/ct+NlsogiEyB/3XXntZhm7Seu/2UdO5VNSFzQlW03m+6r226Tv/17oMPR8+ZF6z/jY+igJBhOQIAD8pKfSau+ju/mSJMVdKCkM+AYWQKiDHYwS5LJIKsdK3sRIIuXbDeijo2EgiwV9HniUbloD6ElDpTf0VAj4s30ZYxIJGfy0S4ZIOsmummBk+jUEoi3GqwFMNpgMRwpVVTnDdI+opVOk6trSf0F9dv2sD8j20jXBR1lrSLN/7RXgpd+iunivJ1191AxdLsDuz/nFkUye1fGDwc/lM6BaO3/ADbFVJTpg3ro7NvUt22T9uVq5X87jRLbJ2kNkKhtiz+cAaeEp5M++Lxl9kWTDgHOQY5p/YhZnuyri7yschIqyKU3KOGMxOPns+/BOpSRS+XrJwmXxRlYGqSQKgy+ryI8XC3k97/p8tSuaYbPQr9CN1x18TPxQ5quLn9rvjYVjlyOuF2bwxV3hHiqECn+y/IYTx6Mzagk1wLeixYb8Xwgu270DzyEooac15kAfGJxeeCer1Ao/UJpahJFOsc31xKeleufyUfducCO4jFEcsipVCBAvMWY9XeFGSv0byE5CO6GkFNwZIvArnKWahGkDBg7cMehp6QdvwuzxJCDUeZLXg2ESdXoFHgVFpk/o4wRBcrC1N1bNbcwhLasKisSxN02y81qeyCxuVc3cfvdPz4MPLsIRRqUzIupayramNsUI83+35+JhIA3UGCCIxt77btVFg8c77untKWHEVc5hquN1/KofSBHYAcL7C+Ja//nGCSSyPQd8dU15V1hMzA4ts8re07eEPFxkozpGMviDLO5w1iDuKb0nf5A3V+5sFhakMzL4Pdy269m43vuUXU+teop0q+nSt2/TOTqd524FU28ZTpTgR37fdp8brdKA5PrfguPJfTHWLBoo6o7mQxEcyEyLIypQe713klLK1fp6IJsKw1GwT9CJI7PQppIxCGqPKIP9uDtVNvKG0UcX05L+L4E9k88j5i7ZuCvb0P92bbMLmld1Thsx2OdGCbCDjdnDdgAJFFRDSdZmL8GbaZHRNhojQ5Q0UEJrs7P+ow+2pfl+mfxn1H8cALc6uceC+MpZqyyNp+CEzDL/gVdugmuXm5BeFKOTwomn5aZ5uZ/2NcobHyym9DyLqFhUjalN3kaR4eAGRBy0ey+SYuaSHVbLLwenKw2KPWQeitadbjOyFowwFOU5ZTnRqC5JedBLq8wYCGqdihmT0+GfvL8KMU8bE2AUSXBz4RdUdIPyeqXdXZT+L79Xf0T63FrZjSTP8AqyZh+0xrNhVycWFXGRPN3GgfisEFI9+fFSWsMqqn+1g98btMfQMBixd2H47ZXWjgpbULHVjbE7nGiaa4Dauwr72SuGvU608B2EZcgdF9SrpXCjwarJz5ntdAc3erS/I=--cnVnlQsoPPSaGR9D--QaXFsqNdQvQ/Hw7vpmCLuw== \ No newline at end of file +kI9E6SyaQdN6XBOjJ4tUTa7ZQ8GT9KWaNZgueI/XDHmkB7bukelJWMPL2WUFMy4GHTPmJPXhqjkmIbMFsKQiDLwYCiCY9s1eKHRvod1x1cj32/cADgo+ttI6+FIQWI1qZg87gL3oRAbpbCxBekYtOJk5btP1nZIixyqPA3XseeGx+vIMgw1uLaS2cGj3ck/CInyZQLInmlyZhnBGyF1s7RRX4l1z7Kt7v94cUskBjLwtnOwyMvbo1fTF2i0dUmXSKptADR+Giw67TivtUsnfhlKD1yt72UEZIGu6TzNxaqE/PKulBe4xuEgehH7lBugeqiHTPndtnzylqJk8JAmLWi0zoVQv7KTFaguQr9FctWE7vSDK4R+k2IET1vDkIMweLGttuAISHNa/u23ubUh0kn1k64iSN5xmzqVxtI+DWEn3WqW21CPnl+FezfcCC+aaN9yzG4tUwgv95XmHEKyB3ilhV2PzGGLCyrBLClels4zeS6Xk8kb/SmctFOEQ+00L9qA/cf0o9gkcRe1aNZSVGm8BNrFBt7kXmCMpaJpgfxP2z6s60DH4LUW3UYhCOlljPCy3q6GKUgUkfnQFZyur6eO5lUSpEF7IVaOry/fGkCmM/L+MPJNBX7FPUTQvWCf4WDskrhF4nHlTHp8/peOYS+M2dCA/XCc+Vr4ZhHYPfH+Woy2YJ+IMMzoTm/AJ/HHDDzUWp+l5pwuvQkTZWPRmP1RIH51sl3DrK3y0tQ5AVFsCTUY9SrDYKa1/uXBmerM5n5Nr7vyGHFKtHomkxz9veOb4eLCMcN7U/D7QpHHfnU+qlRGEv77eIAE49+resnb4Fn89/Wf534LE7GOf9IbYDUMsXCqMakGdzkQh3mqUuahrEG7Q8QbmZ1rLFk4S1vldo4+MXItB8jOjy5LwqJkjPaQg9edA9nuoQ4jP6XHgpuetYHZnQpBEm1aulB+dG8NgPpOCLTrGL6I9v3III+B06B34dtkkyPHEfqkG3s/Shph46W8VT9DJTktGeyhJ7xzgo7rJFv8sRv3SBQuNYYOBahDsFmlHazCyaDsXuR49ir6L2zOaDj9aeazcPam3EccodmZqHTVWnKaB6TSQX/+X0u96R5WDJGxkOh6MMPd+gIShW/96O8nQpK18F/fdfCBpmM6QwbF6lb80zDGNXbx9qH2a4bRfoW3AGAfXSD/ehzzqZAP4fmoVoT4p1EUAAz1pTYqNdhOjxfEt6u545yTKdcT8YTfVd2Jnyj+3mRntDpleauV9A07XneenI3NyQPCfxNwZALVJ1Zg22/aY+1vJdiK8WkBrKqvkbDP8yqCauDDRR/Rk8e/mbbjdRkBY5zijLdM2WCjB2uy0gKVrBr8BtzeiXiVYR4rKMNyKgIcwuGOX68NSZvUiXaVx6Pnk56hHjDJuxEJoYCBi3g6QA1JWY+onau10MC2BdtA/Z0xpxewXmLTrQq7bHNLwd3OJJ7abM952qr932yh3ileCj4He8fdhgXOHTEwLuH3CwC8i3IkZE5LRvLWU5mRK5nEf5bKVLTe6X9nVi5Yarm/lMQr1YTwX14rWaR/hTo5qm5yJzz5+WJVsXqH3ASkb/VWTob2uNUFk3MuXfxn4ksXTmJBvt3d0+hYd3W5fbO8XhEsUPziqDa752XB4O6csnYHR/cxA6acB2nvSrJXVzLHkwuqevIYiZ6Cdg06Uw8QLv0H3KmM4hNNaxR+GFEysEVT69f2qQZzqaCluMboj0wO+ebzcsc4Z7LPt/NmWt0Gi+fol--72FPeAqvxPtPmx2/--If1Hki/TxWi7If032tO13Q== \ No newline at end of file diff --git a/config/credentials/staging.yml.enc b/config/credentials/staging.yml.enc index 0a007e35d..a290917c3 100644 --- a/config/credentials/staging.yml.enc +++ b/config/credentials/staging.yml.enc @@ -1 +1 @@ -9JD9jNdU7DCiqe0LAHSWFuB7ANmPinU32C0Fv1YkQhItRWtWKcGo+fsbv/Z/T2UbwKB8CMBRM2zwL4sKedcWBw+uTACeA/86k1kQJXuLZO/X3XuTAf2jOLLLo11YLXBYthN2tkXl+qXH2dyOvZxjSsAc+pKKe1VZkl7+XIgikEgXZw2lSjf7RV9XS3i/QwO63XkedHuTbLTSPh4U9pCsa8oFALQzVyenBiLtgi2PIbFXdYpzdd5ZlDinWGFIz7rg2qIe2s1q0bVFjMSCi+7n7yLtS0yZy7jYVfvXBh2bOrfKGd8L+9akOG1nhWu7FaY/4wxxnlaTeN9uBqZkbVOPpecE35MYmjhpuw+PCaSiussADICqutiSPkqXpUtZHPYJ2EGcT1p6aRBU9ZQzs2eywVOp5rcbuKVVnUdEb6JLNt81OLiG0Mh3efq2q9bDTT9ygBReRqFVNr/sNq4wWPTb1dBbua8q44zJmDzL659mJZWlyPZjjIga+vrq/KfYQ7XIluZk17Fd4ESJ09a8AAYvDF1alzWsEs4ne2/SZGZHlDczrQEb4kq12h2PwKx5PNxdJQudrCR3acp8D6gjHr0XOGHcbH6jwaWe2VLXp1ovx4pf6su9JsvhJ+2wdPyeBof4vLGPhakScor8BVefVo88yYGUFvXV43NGIwbHlJYlUqv60jV17stiwKhVddUDyEdL34DJqCMYn1PuEsvAIKhVVKKPV/MPZT2PXto0QU5eD/167caa5JFMSYxNvUfIrgRAEtvhBJlnSB5psKi8DVIWt6rFPHDQoykVl6Ow5tkJCheXnggsrZX/a+SzyC6nqWXf9Dw1p1d7lIaaH+bSuiugBZTAZj5MmE9t/yOJMWmpN8+OXf4CErlcFIlphg3EBP8TTK8A44dMEzAvqABcpyCAsBi+spOg55lpmJAdbWwm+OtQ1fgOFS0CrShCIMs0gAOAaZQQKLgVaWHx93y1Fx0e5qP8B+CzxKBjZY1YgCTfPORGD71VZhOhA0X7zme9Ot0Y1DmQ04aQvqRmACrEN95pyqYZ7FWFFG1Mzy2VGb7INpeiXBaWPpaoWCdOkh7SBB+Foj6klXY1hbB+jPaxP4jqsOMheVXBLMRcJCps1Ax+mTqiMN9OHi0ibT2kGS+Ir/CuLtHTPTMD1mkHQN4PNH7HTemCdk0Fi87PAYtdG/f4IqlFAvPI5VSp04wDv1vN9iSxSVOjO6n2DULcAjhT22DHU87Lb2vsvzRNG88GoY9gGmOKiEUxkwKWV85/D3MzV376kY6R699jfsh7Ms2GiyWH5fKD3ZqS+LdN7+0bkarPdKYqtBaB/e2Gsx1YHB1l8ZW3IpXONA0s8gvH+OxJg3xNaH13m8DZKPK20ZOZWdW+3VIF/54e2NhS49D4KXutuo5xB2YGSRLpDSMoIYscJID7cc+VK2Gqmf07AlvpmUYW2S2mO5dgzu+KOPVzBkTQ+rhUsthEdUIpQXn1y94SLlxgJcMlA3deqXLfQZwKG/mNAuqmvx/t5xkMyvhz3OdGHek2Os6wesQ/t4TqkUs4iY6WHolZ0TARP+hRDRtLMdNtwP7V0vSfWSvrZut9UypfEqKlrWtiPIgpZlRaro8uQkoaweTpPR6CQJ6klnsoOQj6B7pbscg9E6X4tM15Ld8IogItn9Ted5OyxwroWUc=--ikgyIcb4z3MncQnj--HZOkrCFarVAis0DMXy0oaw== \ No newline at end of file +TbB/elcmqQxp+kROraLOMdJvcR7ASGUEf57su2byIMFaa9KN8XoWIe7S/xPI2/eps27VAS51sLovETSAYVYupDdadGKuAAWPh4uTcAJsHmbXueggO1EE5GA6SGK1si87m/31ZC8UNVtyAb4dE5wh0lhbmHx1trYhDcF1ofpyxXWKrIGxP8KNDTJJFlAVV7ycWT7OCSAAhSDyDuQXP2EIs3i1IObPgoSUtnKqx8yLkTAMKIpqYdpSS51nrI3mB2WBkpeOslGRJ9Fz1t84LGwu7r9dYlNfwwVQee7vQoWKcSwWGUxh0z6Of7fxa2SdHkcRxsA8T198NNj70S3enNwoZATav8cUgGEIGBbh9nPZcOKqiAXJxrwT6sx7TfdURpYBkEox/9pD2hHyMocTeqiPQF1CwwiP5lYwCJrc+BezRM9WxvJyoHEzll/lkztN1ZOwm2vHLp388j9w2RdGlSNDgJgLzIlXXJUNTmUBr82cQG7trR8cYfS/eMuOb1OuBr1/NZYlA5aOxrJ3ihvK6JcuSpoi42EJqLjh6uf+9Fk75SkSK8QYgFF9T/y69YWasau3GG1VUKDSlJNJGUuKke80dDIE0pf9CI8JXN3+rINE2t/gReExe52FAjZGn5UtMbkMs6K4HojkuAtkCZ+Q2fXIqlVMBOmTGGBDJK0SGWeBb/7MkunKcQGtGPqg+MI6yKTbfE6WKJphx6fUgBVLGfkfjSeNFwgTGVcSTVOvrd0SyOgs0jN7tmlTYeKOKJu0WI/ZE3xKIW/fwcX38KuC1eTPFVVE/N0NoQccDY0cmNJ2sb6tTvTxC4pym21uRNYgG0SdRh4qd2uNJOwQN9buB7tfjAWcbbrCDl22VxMM3N7I979O8YekWrxwuVHkdFtGTleP2LAl94YK36zBWH/zptxHh3asjJQue/2ljjBw7mVxpprwJbTMw12OZWxsPekys/fozXDSCEhIkkTesRVi0zlY/PSko1Hco1FY2kSa4enkh5/sTWJwO0ApkgIonbRVMWh44T5aUB7bAha/7ocK9VhInl6W1j7hepCtlHtY5pk7gBDJzxIAVgMH6tgWZ94Z8Qf4quDy499PoIp/M+3bTl4zdspuW+HyeOc1hlY5sH4cH/SbJ7ViE0HL0n+cW51yqatWnoWEgdVa5rAXYmGvb2vPZHi4FGFurIsRs39q8F7DICNdzTD4sVXr3AwX4FQPyUj7oRTUHF8BNs/dVfheeytVEztnhAtG0NS3dFh0/1CSvYJh1jqeU8G0NLCwC9JJ491cpxAwqmPqxXa5giYoUpnmk9kAqOHWp7RdFtxXiYmVdZ/temx5pfdlg1/BRYw3HUv6L8tgiHTHxo4+TJjwIRll4jNdE4jOpNLNgVINwWCVZnqLv934PjUkOB6vKPRKA6xXHLV13BKRNke7yVF+/6YeB/jDi3vVD5f1tnlhKHSQ6sp+oW78Wr/f8OEiABWPEdxNnHInkVHkyxAJyN77dNWHX28D92PNHS4bq29Op6/0qGtxKSnZ+uMOStTefJfB60KpJnPRqA175CBdNrPmnZmvh+HBwCXeLr4ILiLynQJuwvmONqlH9TwrkuXvXUaQV5YfWsu5KqeVMbNhC9fsVe3C57jd86U9+8JVl3L6LxUqFfBvDwqC3RR3wJAXCykHN76HWLzacMokfgC3qmu+jihqXLAXEEr7bMJrV77mDSukzgU48vt+9J27QfHZshdm5aABCu2lQx+7AI8ZrNgNVO+j0mOr8dxgtEQ+AylLPcbzf8sn/knr4/G1rdxUv9BkkxY0gbWOHS0Tr3Oqyn+DgVF3wuQOU0slcXa1rBlATWCK4xphTrsPzXbZ2/br2hjzPBdw--SnT5ipZ6Jr48x3Mu--mJVJxv0C6+5hN6kVvoYr6g== \ No newline at end of file diff --git a/config/credentials/test.yml.enc b/config/credentials/test.yml.enc index de8b4b441..fe826246b 100644 --- a/config/credentials/test.yml.enc +++ b/config/credentials/test.yml.enc @@ -1 +1 @@ -ADXpePqAwH/J5T8SGYvBbmZcw5VWezhEngFQVDYROdye9KoQ6OJ46aNYpBQW2W6wofG2IBQq19hpNcI8/X31I1RMOyvcRCnfeJ8nSFiCEH/6vnxySB3gpxEMfosQ2BZs3QOWe/ulB3JcoZE1nFMbD8GTBXK8U7YUHUNeAqJowOQ/5AE0/jVkDkoV2s/cZAdiSxAdvSU+flib16yrjVKdPlyyLDs6lnyNx9deps8Hd/FYy09bBvJ8srROXBLPpCaagYoKvxHSJTidj/n9yQ29Pdj4vyylaDaN2kCXZAVQ+XTwM/hz8bBhYlZZ6McWQU9QHyM/WeU7pTPMy+yNVTUvF2A5z4vd4vW4fON1rUOlHSULUNSyhvSWfZcmXF4LTpKX5By0qOFs8fbUrUZI2upto1wcCDL2e4bbw2TXxL1sZSNBzBN8da7w4pKeCppJshA4glDGN+z7jWHnn8mD1lqG1YuoVsmGwLDnoWbvQ+Ke5+0VVLiH4A6pzWC+oD0ZQF8ENDT8LpFwojwwB6EsfECG0GjWcEFEWyWddYTQ4QEv8360U/gpWAAZUp5Qcc9V5QZ+XNzFJS6Q3fLGxK+juOnRMcc8DJTEZUlFIemB6fDTAUCUODLjJdBYmj2rL+la4Ib8zYozqoLHNQYPPKentwl0bgQQSHiDMkXohDLb8nYcvg66KGdcRdvCtE7y1Q5vgNX4C+CkrWNGuynuQ4wpHnQ/b7vmJQYNpaDjNsHpkjSxnBACBz7RgLFA+xtF0JAYTvW8jbrWQNDrTzp1SZA/53RBZYRsbNUJ0g8FHkFQTZpvsLDVw/0A6uv2avnOrtM3N//v+arwMU6Pmw5uy4iK9OhzExmjf+wfsmBwDHWyMF54nzN0uW7kwpau5b5lmiRhYYxVfJZyPUm0Pyvba/ZhkznYOtItA+xiTLpeJrghqXD5TCDl8r3bvVACQzQsBcYCC7kbWPJ3AKfsH7ml7v5zVj2a1gx8JZ+TKIF9i97lbOZ9XrktmdFmXsVE4CmFkpYpwWfzmOoO4hJQDqNu5164WyUEEURPNVa1e+nmtQNB6rK0ckL+nJ0bQDoVEx1JgJcgvkGlUF41vv2i4v0gqI7lECsCaLTnL9czKuKMf/BwYOSZVttBaSJDGi2HVbXmWfBdbJrcR4oVs/Y+UJ17Pi8PBA5k4L/Tzc9LZ4b4WgX3A7TYMdTMASTaILOMA8QC1uqz4+YIvp7TI4spOtQz6djrzMkNpQoyogcXWvxFIeYhetEz6W+RHKOQe6GMLYY9sQQ5E0DNcICkVpJ2IuixDdpE2tU5U9IaCofJ3dMWx32vH8xTqXyvzQRS0b2NXBw/7zn15qs5I+T1JiS+L/EWDf/HyPlsqiZsFSkiAdmmZPV6eOGd2L/eZ0RmmKna2bMeuCdk44oREJxW9nrTobODsX+CYLCqN+ckNIQW9BxDoBkIdh7hM+omM3SW5ZYL5LQby8z/YsIMECkdf7Pj4bD5+KSvJ2UMP8mnCMghXMYJJd3oKZCkij1oZhrelYYp9APNKF3wsG7skJoO7iBc+v+aAi95FKPo64wy+xySICXVd1/SCI2Gqiju0FvGTVcLt0hcmmG01mA4nGX5b3f5AzX/x7g1HjxEdL80AyEAPW5/o94yE2eOaWHwCEDRbp6xwT8vMtobyyB0Lm/ns4vA3UBljmafsvzUBWBEhid83ns0IjSWzVYtuY2PrU/E3/i9Btw0J2oa1va89iA/yWFH1O4dZhdfhSUFt6HE1ydf16GRoLINHbTzVolJCtlivfdP2oRzFQDKrmQaXYGSMGbxLHNam45CopHPWThkx1AY9xs=--qBCUG6JSF8JVLmIJ--BlPRDPPc+M7l/sFLkzoRDQ== \ No newline at end of file +5yjN1qvY9r3z4c2j7iLIuEMFr+4Mc1ytXDvkBx3+NVyHAZctBhpI8g2F2OXYq9zTLcgGhTGLLtI2w/HFIXd8+vAUljvR37r/YnzKRxzTRNC+j3O9Jle3qxbx5v5yg/SNM9JmeY3cEVvVaPnUgvSnOWmmiMfyZlKEFlx0Mbk6hbqGz1z1nxZwQFpGQ344s/S3MinI+VeOpjrnMYTdjZFMTKSlAkbpxWSOo5rg087leH28cFVK2+blOvMXfVWRJaquY9p6sPV5C9X+Q36uX0q2abuWFpIe0vBlHDcwL3iHq0oymei/BANQD76uLUONyffPRogU3RvbZjMWd/o34SMZ4rUmNUXAKl/LdmjbDZFBAMdigQnpMajIWdzHtNA6IWFvM6f5mv4euBazMsM5MKNg9787w1k6CDqQh7kwXIF6GthQuhjpdSSQmdE0D6KW1xkRWcj0wIWligMuZC96GepwJKQDwf4if27I5RKZ8v4PfU0EsHVhRzKc9E6yYpPXA7l+Q3+kYpqXLBaG4Ga3FKwaFPcU+ZFXqFRaXz3SEqt5Vy4nzQ62q2oQO0/Kglm3zt/eE3KJrpYWb5xGrGNHWQe7H8QQ6wGJjIB/YMF1BGkauXC4DUGZZ1vDCaxWAi/pRd0gsKCVdiZE0jJ7BEK4tvNyFtoeyHVMYFhlrjl9bZm1oOwlefzIO5gv+Wrquyr49RNtY3QZ1fLhF9pakZE6ZvS/Vy7LvnASw/rBBZpYSVFPwnFhVjyBh2WrqTQ7hb17S3MqrOnU+AFp5Y7kC1s9SfqRz+myraw2roYWl+ouFrApLUUfGWekjLDZKPfYvxhnN7hscb82Dw8EC23dIk89VjrA3yxUg0Hj32azxd1jhWakKIeslz02pAyfqg8KkNfL6VJmsFg49BGNhH3kay9UgWry/7gfJRRHKRwmHdDdFsYb+ylo11v7V06nLPS72gcPOvcQdt03MzvvmhCz6MEYK9m2mtrHZ10bpll0DataB3NnoFwl2jAusprX0lBOyMbYp1pMEwniXZHpekwmRUH2etM5jySfKiPnGzLtsZ7J6roENxPIZzXJgqYPXMex/i5GanPr4c4J91RYI2s4lYbuAZ1uBI+IAC1WTnq9pHuQy+uRBwWSIhERbMzsPkznWF/lp5C6afHEqztwY7VxemUjj4nGtv0/vrBeyBNx9rWdFGWG+BalKTInRuXZmT0RCSv1YtU608QpA8kvj8lYRAcpf5T7fOl9k1FXG4jNW6twRIRDG/l0Q7SP9rOOhciaWfWfalYubaUwAEpMMz0ULT1p32jKajuf+/kYJAmaT7F6P6KZe7IYgCvgQrPt+8XumQOITVchqEU9poE6fS/BC4WCet9FVqJykxHfJGgd1+cKKtB2vJnHlVJG0+TDHviKYNlGa/SulA3K1iEhSIGc9Awy7N5JuzN+JP8KN8acHcadwdCwe9vqncqz3t9ZPDDv9/c7CYJi6LbrgCbaBxI2xMaLOK1Gyc4bctO2t+YkS1XwqK7SBp4pz/U4Z9PLKuG6kOaNkKgSNZL//tqrnbYLaQXiPVQVOQIqhG+BVxl4gxeiYrrNH5VeQDWDW1dBg7Zy7E5aa+WGlM+9KNRo4Uuvdtp0VaD7vDGlYPz5GLXaJqBQmBYvHnSGKRw65/alFdhpyawFtgHG5Mpo8klfIQZo9GFysTNuyhowJxZgva8ip//DKtioQ5ZiNqi4T7JWuPVvowZnnORCUqApwIDD0sp5mBISHh3sbikCIeoor6JG245CBVANBEobHa7ub2RUTEa7oS31aK+KGUvbetdNqLoDavdjKi9T0WaABJBpfn7bw2YE6z9nM+hkiwlY7otNGKu7+7aNBikUL4iaa+N6uahyvKm78VqEmac5NS3ZuRySv1Kix9/K7lVAnou+hdN/TsAJprfsXjsxsidok1QBvU1RFSlog8h+ww==--emrCOiutLVO3FHMz--UVUGcuJTrHwOoVo9AKubUQ== \ No newline at end of file diff --git a/spec/clients/insee_sirene_api_client_spec.rb b/spec/clients/insee_sirene_api_client_spec.rb new file mode 100644 index 000000000..1695076fe --- /dev/null +++ b/spec/clients/insee_sirene_api_client_spec.rb @@ -0,0 +1,43 @@ +RSpec.describe INSEESireneAPIClient do + let(:insee_api_authentication) { instance_double(INSEEAPIAuthentication, access_token: 'access_token') } + + before do + allow(INSEEAPIAuthentication).to receive(:new).and_return(insee_api_authentication) + end + + describe '#etablissement' do + subject(:etablissement_payload) { described_class.new.etablissement(siret:) } + + let(:siret) { '13002526500013' } + + context 'when the API returns a 200' do + let(:valid_payload) { insee_sirene_api_etablissement_valid_payload(siret:) } + + before do + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{siret}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: valid_payload.to_json + ) + end + + it 'renders a valid json from payload' do + expect(etablissement_payload).to eq(valid_payload) + end + end + + context 'when API returns something else than 200' do + before do + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{siret}").to_return( + status: 404, + headers: { 'Content-Type' => 'application/json' }, + body: '' + ) + end + + it 'raises an error' do + expect { etablissement_payload }.to raise_error(Faraday::Error) + end + end + end +end diff --git a/spec/fixtures/insee/13002526500013.json b/spec/fixtures/insee/13002526500013.json new file mode 100644 index 000000000..af5c31feb --- /dev/null +++ b/spec/fixtures/insee/13002526500013.json @@ -0,0 +1,102 @@ +{ + "header": { + "statut": 200, + "message": "ok" + }, + "etablissement": { + "siren": "130025265", + "nic": "00013", + "siret": "13002526500013", + "statutDiffusionEtablissement": "O", + "dateCreationEtablissement": "2017-05-24", + "trancheEffectifsEtablissement": "22", + "anneeEffectifsEtablissement": "2021", + "activitePrincipaleRegistreMetiersEtablissement": null, + "dateDernierTraitementEtablissement": "2023-11-30T10:17:12", + "etablissementSiege": true, + "nombrePeriodesEtablissement": 1, + "uniteLegale": { + "etatAdministratifUniteLegale": "A", + "statutDiffusionUniteLegale": "O", + "dateCreationUniteLegale": "2017-05-24", + "categorieJuridiqueUniteLegale": "7120", + "denominationUniteLegale": "DIRECTION INTERMINISTERIELLE DU NUMERIQUE", + "sigleUniteLegale": "DINUM", + "denominationUsuelle1UniteLegale": null, + "denominationUsuelle2UniteLegale": null, + "denominationUsuelle3UniteLegale": null, + "sexeUniteLegale": null, + "nomUniteLegale": null, + "nomUsageUniteLegale": null, + "prenom1UniteLegale": null, + "prenom2UniteLegale": null, + "prenom3UniteLegale": null, + "prenom4UniteLegale": null, + "prenomUsuelUniteLegale": null, + "pseudonymeUniteLegale": null, + "activitePrincipaleUniteLegale": "84.11Z", + "nomenclatureActivitePrincipaleUniteLegale": "NAFRev2", + "identifiantAssociationUniteLegale": null, + "economieSocialeSolidaireUniteLegale": "N", + "societeMissionUniteLegale": null, + "caractereEmployeurUniteLegale": "N", + "trancheEffectifsUniteLegale": "22", + "anneeEffectifsUniteLegale": "2021", + "nicSiegeUniteLegale": "00013", + "dateDernierTraitementUniteLegale": "2023-11-30T10:17:13", + "categorieEntreprise": "PME", + "anneeCategorieEntreprise": "2021" + }, + "adresseEtablissement": { + "complementAdresseEtablissement": null, + "numeroVoieEtablissement": "20", + "indiceRepetitionEtablissement": null, + "typeVoieEtablissement": "AV", + "libelleVoieEtablissement": "DE SEGUR", + "codePostalEtablissement": "75007", + "libelleCommuneEtablissement": "PARIS 7", + "libelleCommuneEtrangerEtablissement": null, + "distributionSpecialeEtablissement": null, + "codeCommuneEtablissement": "75107", + "codeCedexEtablissement": null, + "libelleCedexEtablissement": null, + "codePaysEtrangerEtablissement": null, + "libellePaysEtrangerEtablissement": null + }, + "adresse2Etablissement": { + "complementAdresse2Etablissement": null, + "numeroVoie2Etablissement": null, + "indiceRepetition2Etablissement": null, + "typeVoie2Etablissement": null, + "libelleVoie2Etablissement": null, + "codePostal2Etablissement": null, + "libelleCommune2Etablissement": null, + "libelleCommuneEtranger2Etablissement": null, + "distributionSpeciale2Etablissement": null, + "codeCommune2Etablissement": null, + "codeCedex2Etablissement": null, + "libelleCedex2Etablissement": null, + "codePaysEtranger2Etablissement": null, + "libellePaysEtranger2Etablissement": null + }, + "periodesEtablissement": [ + { + "dateFin": null, + "dateDebut": "2017-05-24", + "etatAdministratifEtablissement": "A", + "changementEtatAdministratifEtablissement": false, + "enseigne1Etablissement": null, + "enseigne2Etablissement": null, + "enseigne3Etablissement": null, + "changementEnseigneEtablissement": false, + "denominationUsuelleEtablissement": null, + "changementDenominationUsuelleEtablissement": false, + "activitePrincipaleEtablissement": "84.11Z", + "nomenclatureActivitePrincipaleEtablissement": "NAFRev2", + "changementActivitePrincipaleEtablissement": false, + "caractereEmployeurEtablissement": "N", + "changementCaractereEmployeurEtablissement": false + } + ] + } +} \ No newline at end of file diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index f63c9ac57..f6447e6c4 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -84,6 +84,8 @@ config.include SpecsHelper config.include FeatureHelper, type: :feature config.include ExternalUrlHelper, type: :feature + config.include FixturesHelpers + config.include INSEESireneAPIMocks config.around(:each, :js) do |example| example.run_with_retry retry: example.metadata[:retry] || 3 diff --git a/spec/support/fixtures_helpers.rb b/spec/support/fixtures_helpers.rb new file mode 100644 index 000000000..430021fe4 --- /dev/null +++ b/spec/support/fixtures_helpers.rb @@ -0,0 +1,17 @@ +module FixturesHelpers + def fixture_exists?(path) + Rails.root.join('spec', 'fixtures', path).exist? + end + + def open_fixture(path) + File.open(File.join(File.dirname(__FILE__), '..', 'fixtures', path)) + end + + def read_fixture(path) + open_fixture(path).read + end + + def read_json_fixture(path) + JSON.parse(open_fixture(path).read) + end +end diff --git a/spec/support/insee_sirene_api_mocks.rb b/spec/support/insee_sirene_api_mocks.rb new file mode 100644 index 000000000..2c56643c4 --- /dev/null +++ b/spec/support/insee_sirene_api_mocks.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module INSEESireneAPIMocks + def insee_sirene_api_etablissement_valid_payload(siret:, full: false) + if full + read_json_fixture("insee/#{siret}.json") + else + { + 'header' => { + 'statut' => 200, + 'message' => 'OK' + }, + 'etablissement' => { + 'siren' => siret.first(9) + } + } + end + end + + def insee_sirene_api_not_found_payload + { + 'header' => { + 'statut' => 404, + 'message' => 'Not Found' + } + } + end +end From 610c7a9a5d18bd6c94e33ed9cf3e6e68a668372d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Fri, 21 Jun 2024 14:43:20 +0200 Subject: [PATCH 08/16] Introduce Organization model Will be used for HubEE --- app/models/authorization_request.rb | 4 ++++ app/models/organization.rb | 37 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 app/models/organization.rb diff --git a/app/models/authorization_request.rb b/app/models/authorization_request.rb index c28ca94fc..d9afc014e 100644 --- a/app/models/authorization_request.rb +++ b/app/models/authorization_request.rb @@ -76,6 +76,10 @@ def most_recent_token has_one :contact_technique, through: :contact_technique_authorization_request_role has_one :contact_metier, through: :contact_metier_authorization_request_role + def organization + @organization ||= Organization.new(siret) + end + def contacts_no_demandeur contacts.reject { |user| user == demandeur } end diff --git a/app/models/organization.rb b/app/models/organization.rb new file mode 100644 index 000000000..d3bb2917f --- /dev/null +++ b/app/models/organization.rb @@ -0,0 +1,37 @@ +class Organization + attr_reader :siret + + def initialize(siret) + @siret = siret + end + + def denomination + unite_legale_insee_payload['denominationUniteLegale'] + end + + def code_commune_etablissement + adresse_etablissement_insee_payload['codeCommuneEtablissement'] + end + + def code_postal_etablissement + adresse_etablissement_insee_payload['codePostalEtablissement'] + end + + private + + def adresse_etablissement_insee_payload + etablissement_insee_payload['adresseEtablissement'] + end + + def etablissement_insee_payload + insee_payload['etablissement'] + end + + def unite_legale_insee_payload + etablissement_insee_payload['uniteLegale'] + end + + def insee_payload + @insee_payload ||= INSEESireneAPIClient.new.etablissement(siret:) + end +end From 1dbbbf18988a445d932ea02ee5d611fb050f9fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Fri, 21 Jun 2024 16:31:12 +0200 Subject: [PATCH 09/16] Introduce HubEEAPIClient --- app/clients/abstract_hubee_api_client.rb | 23 ++++++++ app/clients/hubee_api_authentication.rb | 21 +++++++ app/clients/hubee_api_client.rb | 75 ++++++++++++++++++++++++ config/credentials/production.yml.enc | 2 +- config/credentials/sandbox.yml.enc | 2 +- config/credentials/staging.yml.enc | 2 +- config/credentials/test.yml.enc | 2 +- spec/clients/hubee_api_client_spec.rb | 67 +++++++++++++++++++++ spec/rails_helper.rb | 1 + spec/support/hubee_api_mocks.rb | 40 +++++++++++++ 10 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 app/clients/abstract_hubee_api_client.rb create mode 100644 app/clients/hubee_api_authentication.rb create mode 100644 app/clients/hubee_api_client.rb create mode 100644 spec/clients/hubee_api_client_spec.rb create mode 100644 spec/support/hubee_api_mocks.rb diff --git a/app/clients/abstract_hubee_api_client.rb b/app/clients/abstract_hubee_api_client.rb new file mode 100644 index 000000000..934b0e481 --- /dev/null +++ b/app/clients/abstract_hubee_api_client.rb @@ -0,0 +1,23 @@ +require 'faraday' + +class AbstractHubEEAPIClient + protected + + def http_connection(&block) + @http_connection ||= Faraday.new do |conn| + conn.request :retry, max: 5 + conn.response :raise_error + conn.response :json + conn.options.timeout = 2 + yield(conn) if block + end + end + + def consumer_key + Rails.application.credentials.hubee_consumer_key + end + + def consumer_secret + Rails.application.credentials.hubee_consumer_secret + end +end diff --git a/app/clients/hubee_api_authentication.rb b/app/clients/hubee_api_authentication.rb new file mode 100644 index 000000000..953068b63 --- /dev/null +++ b/app/clients/hubee_api_authentication.rb @@ -0,0 +1,21 @@ +class HubEEAPIAuthentication < AbstractHubEEAPIClient + def access_token + http_connection.post( + auth_url, + 'grant_type=client_credentials&scope=ADMIN', + { + 'Authorization' => "Basic #{encoded_client_id_and_secret}" + } + ).body['access_token'] + end + + private + + def auth_url + Rails.application.credentials.hubee_auth_url + end + + def encoded_client_id_and_secret + Base64.strict_encode64("#{consumer_key}:#{consumer_secret}") + end +end diff --git a/app/clients/hubee_api_client.rb b/app/clients/hubee_api_client.rb new file mode 100644 index 000000000..68424f930 --- /dev/null +++ b/app/clients/hubee_api_client.rb @@ -0,0 +1,75 @@ +class HubEEAPIClient < AbstractHubEEAPIClient + class NotFound < StandardError; end + class AlreadyExists < StandardError; end + + def find_organization(organization) + http_connection.get("#{host}/referential/v1/organizations/SI-#{organization.siret}-#{organization.code_commune_etablissement}").body + rescue Faraday::ResourceNotFound + raise NotFound + end + + def create_organization(organization, email) + http_connection.post( + "#{host}/referential/v1/organizations", + { + type: 'SI', + companyRegister: organization.siret, + branchCode: organization.code_commune_etablissement, + email:, + name: organization.denomination, + postalCode: organization.code_postal_etablissement, + territory: organization.code_commune_etablissement, + status: 'Actif' + }.to_json, + 'Content-Type' => 'application/json' + ) + rescue Faraday::BadRequestError => e + raise AlreadyExists if already_exists_error?(e) + + raise + end + + def create_subscription(authorization_request, organization_payload, process_code) + http_connection.post( + "#{host}/referential/v1/subscriptions", + { + datapassId: authorization_request.external_id.to_i, + notificationFrequency: 'unitaire', + processCode: process_code, + subscriber: { + type: 'SI', + companyRegister: organization_payload['companyRegister'], + branchCode: organization_payload['branchCode'] + }, + email: authorization_request.demandeur.email, + status: 'Actif', + localAdministrator: { + email: authorization_request.demandeur.email + } + }.to_json, + 'Content-Type' => 'application/json' + ) + rescue Faraday::BadRequestError => e + raise AlreadyExists if already_exists_error?(e) + + raise + end + + protected + + def host + Rails.application.credentials.hubee_api_url + end + + def already_exists_error?(faraday_error) + faraday_error.response[:body]['errors'].any? do |error| + error['message'].include?('already exists') + end + end + + def http_connection + super do |conn| + conn.request :authorization, 'Bearer', -> { HubEEAPIAuthentication.new.access_token } + end + end +end diff --git a/config/credentials/production.yml.enc b/config/credentials/production.yml.enc index b0e07d3af..224505042 100644 --- a/config/credentials/production.yml.enc +++ b/config/credentials/production.yml.enc @@ -1 +1 @@ -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--tgGTVwo/lU3jhCuB--9N1N4TlMV/Rw+Vk07mxh/w== \ No newline at end of file +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--tgGTVwo/lU3jhCuB--9N1N4TlMV/Rw+Vk07mxh/w== diff --git a/config/credentials/sandbox.yml.enc b/config/credentials/sandbox.yml.enc index d4a03a175..92e621b3b 100644 --- a/config/credentials/sandbox.yml.enc +++ b/config/credentials/sandbox.yml.enc @@ -1 +1 @@ -kI9E6SyaQdN6XBOjJ4tUTa7ZQ8GT9KWaNZgueI/XDHmkB7bukelJWMPL2WUFMy4GHTPmJPXhqjkmIbMFsKQiDLwYCiCY9s1eKHRvod1x1cj32/cADgo+ttI6+FIQWI1qZg87gL3oRAbpbCxBekYtOJk5btP1nZIixyqPA3XseeGx+vIMgw1uLaS2cGj3ck/CInyZQLInmlyZhnBGyF1s7RRX4l1z7Kt7v94cUskBjLwtnOwyMvbo1fTF2i0dUmXSKptADR+Giw67TivtUsnfhlKD1yt72UEZIGu6TzNxaqE/PKulBe4xuEgehH7lBugeqiHTPndtnzylqJk8JAmLWi0zoVQv7KTFaguQr9FctWE7vSDK4R+k2IET1vDkIMweLGttuAISHNa/u23ubUh0kn1k64iSN5xmzqVxtI+DWEn3WqW21CPnl+FezfcCC+aaN9yzG4tUwgv95XmHEKyB3ilhV2PzGGLCyrBLClels4zeS6Xk8kb/SmctFOEQ+00L9qA/cf0o9gkcRe1aNZSVGm8BNrFBt7kXmCMpaJpgfxP2z6s60DH4LUW3UYhCOlljPCy3q6GKUgUkfnQFZyur6eO5lUSpEF7IVaOry/fGkCmM/L+MPJNBX7FPUTQvWCf4WDskrhF4nHlTHp8/peOYS+M2dCA/XCc+Vr4ZhHYPfH+Woy2YJ+IMMzoTm/AJ/HHDDzUWp+l5pwuvQkTZWPRmP1RIH51sl3DrK3y0tQ5AVFsCTUY9SrDYKa1/uXBmerM5n5Nr7vyGHFKtHomkxz9veOb4eLCMcN7U/D7QpHHfnU+qlRGEv77eIAE49+resnb4Fn89/Wf534LE7GOf9IbYDUMsXCqMakGdzkQh3mqUuahrEG7Q8QbmZ1rLFk4S1vldo4+MXItB8jOjy5LwqJkjPaQg9edA9nuoQ4jP6XHgpuetYHZnQpBEm1aulB+dG8NgPpOCLTrGL6I9v3III+B06B34dtkkyPHEfqkG3s/Shph46W8VT9DJTktGeyhJ7xzgo7rJFv8sRv3SBQuNYYOBahDsFmlHazCyaDsXuR49ir6L2zOaDj9aeazcPam3EccodmZqHTVWnKaB6TSQX/+X0u96R5WDJGxkOh6MMPd+gIShW/96O8nQpK18F/fdfCBpmM6QwbF6lb80zDGNXbx9qH2a4bRfoW3AGAfXSD/ehzzqZAP4fmoVoT4p1EUAAz1pTYqNdhOjxfEt6u545yTKdcT8YTfVd2Jnyj+3mRntDpleauV9A07XneenI3NyQPCfxNwZALVJ1Zg22/aY+1vJdiK8WkBrKqvkbDP8yqCauDDRR/Rk8e/mbbjdRkBY5zijLdM2WCjB2uy0gKVrBr8BtzeiXiVYR4rKMNyKgIcwuGOX68NSZvUiXaVx6Pnk56hHjDJuxEJoYCBi3g6QA1JWY+onau10MC2BdtA/Z0xpxewXmLTrQq7bHNLwd3OJJ7abM952qr932yh3ileCj4He8fdhgXOHTEwLuH3CwC8i3IkZE5LRvLWU5mRK5nEf5bKVLTe6X9nVi5Yarm/lMQr1YTwX14rWaR/hTo5qm5yJzz5+WJVsXqH3ASkb/VWTob2uNUFk3MuXfxn4ksXTmJBvt3d0+hYd3W5fbO8XhEsUPziqDa752XB4O6csnYHR/cxA6acB2nvSrJXVzLHkwuqevIYiZ6Cdg06Uw8QLv0H3KmM4hNNaxR+GFEysEVT69f2qQZzqaCluMboj0wO+ebzcsc4Z7LPt/NmWt0Gi+fol--72FPeAqvxPtPmx2/--If1Hki/TxWi7If032tO13Q== \ No newline at end of file +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--sVa2IBBRCHcz0YkY--KqKofsqRXSMfN0XY3PEkxw== \ No newline at end of file diff --git a/config/credentials/staging.yml.enc b/config/credentials/staging.yml.enc index a290917c3..3524d000d 100644 --- a/config/credentials/staging.yml.enc +++ b/config/credentials/staging.yml.enc @@ -1 +1 @@ -TbB/elcmqQxp+kROraLOMdJvcR7ASGUEf57su2byIMFaa9KN8XoWIe7S/xPI2/eps27VAS51sLovETSAYVYupDdadGKuAAWPh4uTcAJsHmbXueggO1EE5GA6SGK1si87m/31ZC8UNVtyAb4dE5wh0lhbmHx1trYhDcF1ofpyxXWKrIGxP8KNDTJJFlAVV7ycWT7OCSAAhSDyDuQXP2EIs3i1IObPgoSUtnKqx8yLkTAMKIpqYdpSS51nrI3mB2WBkpeOslGRJ9Fz1t84LGwu7r9dYlNfwwVQee7vQoWKcSwWGUxh0z6Of7fxa2SdHkcRxsA8T198NNj70S3enNwoZATav8cUgGEIGBbh9nPZcOKqiAXJxrwT6sx7TfdURpYBkEox/9pD2hHyMocTeqiPQF1CwwiP5lYwCJrc+BezRM9WxvJyoHEzll/lkztN1ZOwm2vHLp388j9w2RdGlSNDgJgLzIlXXJUNTmUBr82cQG7trR8cYfS/eMuOb1OuBr1/NZYlA5aOxrJ3ihvK6JcuSpoi42EJqLjh6uf+9Fk75SkSK8QYgFF9T/y69YWasau3GG1VUKDSlJNJGUuKke80dDIE0pf9CI8JXN3+rINE2t/gReExe52FAjZGn5UtMbkMs6K4HojkuAtkCZ+Q2fXIqlVMBOmTGGBDJK0SGWeBb/7MkunKcQGtGPqg+MI6yKTbfE6WKJphx6fUgBVLGfkfjSeNFwgTGVcSTVOvrd0SyOgs0jN7tmlTYeKOKJu0WI/ZE3xKIW/fwcX38KuC1eTPFVVE/N0NoQccDY0cmNJ2sb6tTvTxC4pym21uRNYgG0SdRh4qd2uNJOwQN9buB7tfjAWcbbrCDl22VxMM3N7I979O8YekWrxwuVHkdFtGTleP2LAl94YK36zBWH/zptxHh3asjJQue/2ljjBw7mVxpprwJbTMw12OZWxsPekys/fozXDSCEhIkkTesRVi0zlY/PSko1Hco1FY2kSa4enkh5/sTWJwO0ApkgIonbRVMWh44T5aUB7bAha/7ocK9VhInl6W1j7hepCtlHtY5pk7gBDJzxIAVgMH6tgWZ94Z8Qf4quDy499PoIp/M+3bTl4zdspuW+HyeOc1hlY5sH4cH/SbJ7ViE0HL0n+cW51yqatWnoWEgdVa5rAXYmGvb2vPZHi4FGFurIsRs39q8F7DICNdzTD4sVXr3AwX4FQPyUj7oRTUHF8BNs/dVfheeytVEztnhAtG0NS3dFh0/1CSvYJh1jqeU8G0NLCwC9JJ491cpxAwqmPqxXa5giYoUpnmk9kAqOHWp7RdFtxXiYmVdZ/temx5pfdlg1/BRYw3HUv6L8tgiHTHxo4+TJjwIRll4jNdE4jOpNLNgVINwWCVZnqLv934PjUkOB6vKPRKA6xXHLV13BKRNke7yVF+/6YeB/jDi3vVD5f1tnlhKHSQ6sp+oW78Wr/f8OEiABWPEdxNnHInkVHkyxAJyN77dNWHX28D92PNHS4bq29Op6/0qGtxKSnZ+uMOStTefJfB60KpJnPRqA175CBdNrPmnZmvh+HBwCXeLr4ILiLynQJuwvmONqlH9TwrkuXvXUaQV5YfWsu5KqeVMbNhC9fsVe3C57jd86U9+8JVl3L6LxUqFfBvDwqC3RR3wJAXCykHN76HWLzacMokfgC3qmu+jihqXLAXEEr7bMJrV77mDSukzgU48vt+9J27QfHZshdm5aABCu2lQx+7AI8ZrNgNVO+j0mOr8dxgtEQ+AylLPcbzf8sn/knr4/G1rdxUv9BkkxY0gbWOHS0Tr3Oqyn+DgVF3wuQOU0slcXa1rBlATWCK4xphTrsPzXbZ2/br2hjzPBdw--SnT5ipZ6Jr48x3Mu--mJVJxv0C6+5hN6kVvoYr6g== \ No newline at end of file +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--XsN3Zq365PlsbdKl--Mxes8FOFobS+b+Yx+Ky+Lg== \ No newline at end of file diff --git a/config/credentials/test.yml.enc b/config/credentials/test.yml.enc index fe826246b..4400b7321 100644 --- a/config/credentials/test.yml.enc +++ b/config/credentials/test.yml.enc @@ -1 +1 @@ -5yjN1qvY9r3z4c2j7iLIuEMFr+4Mc1ytXDvkBx3+NVyHAZctBhpI8g2F2OXYq9zTLcgGhTGLLtI2w/HFIXd8+vAUljvR37r/YnzKRxzTRNC+j3O9Jle3qxbx5v5yg/SNM9JmeY3cEVvVaPnUgvSnOWmmiMfyZlKEFlx0Mbk6hbqGz1z1nxZwQFpGQ344s/S3MinI+VeOpjrnMYTdjZFMTKSlAkbpxWSOo5rg087leH28cFVK2+blOvMXfVWRJaquY9p6sPV5C9X+Q36uX0q2abuWFpIe0vBlHDcwL3iHq0oymei/BANQD76uLUONyffPRogU3RvbZjMWd/o34SMZ4rUmNUXAKl/LdmjbDZFBAMdigQnpMajIWdzHtNA6IWFvM6f5mv4euBazMsM5MKNg9787w1k6CDqQh7kwXIF6GthQuhjpdSSQmdE0D6KW1xkRWcj0wIWligMuZC96GepwJKQDwf4if27I5RKZ8v4PfU0EsHVhRzKc9E6yYpPXA7l+Q3+kYpqXLBaG4Ga3FKwaFPcU+ZFXqFRaXz3SEqt5Vy4nzQ62q2oQO0/Kglm3zt/eE3KJrpYWb5xGrGNHWQe7H8QQ6wGJjIB/YMF1BGkauXC4DUGZZ1vDCaxWAi/pRd0gsKCVdiZE0jJ7BEK4tvNyFtoeyHVMYFhlrjl9bZm1oOwlefzIO5gv+Wrquyr49RNtY3QZ1fLhF9pakZE6ZvS/Vy7LvnASw/rBBZpYSVFPwnFhVjyBh2WrqTQ7hb17S3MqrOnU+AFp5Y7kC1s9SfqRz+myraw2roYWl+ouFrApLUUfGWekjLDZKPfYvxhnN7hscb82Dw8EC23dIk89VjrA3yxUg0Hj32azxd1jhWakKIeslz02pAyfqg8KkNfL6VJmsFg49BGNhH3kay9UgWry/7gfJRRHKRwmHdDdFsYb+ylo11v7V06nLPS72gcPOvcQdt03MzvvmhCz6MEYK9m2mtrHZ10bpll0DataB3NnoFwl2jAusprX0lBOyMbYp1pMEwniXZHpekwmRUH2etM5jySfKiPnGzLtsZ7J6roENxPIZzXJgqYPXMex/i5GanPr4c4J91RYI2s4lYbuAZ1uBI+IAC1WTnq9pHuQy+uRBwWSIhERbMzsPkznWF/lp5C6afHEqztwY7VxemUjj4nGtv0/vrBeyBNx9rWdFGWG+BalKTInRuXZmT0RCSv1YtU608QpA8kvj8lYRAcpf5T7fOl9k1FXG4jNW6twRIRDG/l0Q7SP9rOOhciaWfWfalYubaUwAEpMMz0ULT1p32jKajuf+/kYJAmaT7F6P6KZe7IYgCvgQrPt+8XumQOITVchqEU9poE6fS/BC4WCet9FVqJykxHfJGgd1+cKKtB2vJnHlVJG0+TDHviKYNlGa/SulA3K1iEhSIGc9Awy7N5JuzN+JP8KN8acHcadwdCwe9vqncqz3t9ZPDDv9/c7CYJi6LbrgCbaBxI2xMaLOK1Gyc4bctO2t+YkS1XwqK7SBp4pz/U4Z9PLKuG6kOaNkKgSNZL//tqrnbYLaQXiPVQVOQIqhG+BVxl4gxeiYrrNH5VeQDWDW1dBg7Zy7E5aa+WGlM+9KNRo4Uuvdtp0VaD7vDGlYPz5GLXaJqBQmBYvHnSGKRw65/alFdhpyawFtgHG5Mpo8klfIQZo9GFysTNuyhowJxZgva8ip//DKtioQ5ZiNqi4T7JWuPVvowZnnORCUqApwIDD0sp5mBISHh3sbikCIeoor6JG245CBVANBEobHa7ub2RUTEa7oS31aK+KGUvbetdNqLoDavdjKi9T0WaABJBpfn7bw2YE6z9nM+hkiwlY7otNGKu7+7aNBikUL4iaa+N6uahyvKm78VqEmac5NS3ZuRySv1Kix9/K7lVAnou+hdN/TsAJprfsXjsxsidok1QBvU1RFSlog8h+ww==--emrCOiutLVO3FHMz--UVUGcuJTrHwOoVo9AKubUQ== \ No newline at end of file +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--dzjtM4Kf2fi6YpMd--1x7ObL5qvU6eia9C3p7sjA== \ No newline at end of file diff --git a/spec/clients/hubee_api_client_spec.rb b/spec/clients/hubee_api_client_spec.rb new file mode 100644 index 000000000..9e6b335d1 --- /dev/null +++ b/spec/clients/hubee_api_client_spec.rb @@ -0,0 +1,67 @@ +RSpec.describe HubEEAPIClient do + let(:hubee_api_authentication) { instance_double(HubEEAPIAuthentication, access_token: 'access_token') } + + before do + allow(HubEEAPIAuthentication).to receive(:new).and_return(hubee_api_authentication) + end + + describe '#find_organization' do + subject(:find_organization_payload) { described_class.new.find_organization(organization) } + + let(:organization) { Organization.new(siret) } + let(:siret) { '13002526500013' } + let(:code_commune) { '13055' } + let(:host) { Rails.application.credentials.hubee_api_url } + + before do + allow(organization).to receive(:code_commune_etablissement).and_return(code_commune) + end + + context 'when the API returns a 200' do + let(:valid_payload) { hubee_organization_payload(siret:, code_commune:) } + + before do + stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: valid_payload.to_json + ) + end + + it 'renders a valid json from payload' do + expect(find_organization_payload).to eq(valid_payload) + end + end + + context 'when API returns 404' do + before do + stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( + status: 404, + headers: { 'Content-Type' => 'application/json' }, + body: { + 'header' => { + 'statut' => 404, + 'message' => "Aucun élément trouvé pour le siret #{siret}" + } + }.to_json + ) + end + + it 'raises a NotFound error' do + expect { find_organization_payload }.to raise_error(HubEEAPIClient::NotFound) + end + end + + context 'when API returns unknown status' do + before do + stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( + status: 500 + ) + end + + it 'raises an error' do + expect { find_organization_payload }.to raise_error(Faraday::Error) + end + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index f6447e6c4..0ce2ebde0 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -86,6 +86,7 @@ config.include ExternalUrlHelper, type: :feature config.include FixturesHelpers config.include INSEESireneAPIMocks + config.include HubEEAPIMocks config.around(:each, :js) do |example| example.run_with_retry retry: example.metadata[:retry] || 3 diff --git a/spec/support/hubee_api_mocks.rb b/spec/support/hubee_api_mocks.rb new file mode 100644 index 000000000..cc21d99b1 --- /dev/null +++ b/spec/support/hubee_api_mocks.rb @@ -0,0 +1,40 @@ +module HubEEAPIMocks + def hubee_organization_payload(siret: '13002526500013', code_commune: '75017') + { + 'country' => 'France', + 'code' => 'DINUM', + 'postalCode' => '75007', + 'type' => 'SI', + 'companyRegister' => siret, + 'createDateTime' => '2021-05-20T15:59:02.569+00:00', + 'branchCode' => code_commune, + 'phoneNumber' => '0000000000', + 'name' => 'DIRECTION INTERMINISTERIELLE DU NUMERIQUE', + 'updateDateTime' => '2022-01-27T19:42:07.386+00:00', + 'email' => 'datapass@yopmail.com', + 'territory' => 'PARIS 7', + 'status' => 'Actif' + } + end + + def hubee_subscription_payload(authorization_request:, organization_payload: hubee_organization_payload, process_code: 'TEST') + { + 'id' => SecureRandom.uuid, + 'datapassId' => authorization_request.external_id.to_i, + 'notificationFrequency' => 'unitaire', + 'processCode' => process_code, + 'email' => authorization_request.demandeur.email, + 'localAdministrator' => { + 'email' => authorization_request.demandeur.email + }, + 'status' => 'Actif', + 'subscriber' => { + 'branchCode' => organization_payload['branchCode'], + 'companyRegister' => organization_payload['companyRegister'], + 'type' => 'SI' + }, + 'creationDateTime' => '2024-06-24T16:01:27.142+00:00', + 'updateDateTime' => '2024-06-24T16:01:27+0000' + } + end +end From cdf1dc84aa5a234fe1eb5f7f302a7ca2c3225822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Fri, 21 Jun 2024 17:34:07 +0200 Subject: [PATCH 10/16] Introduce CreateFormulaireQFHubEESubscriptionJob --- ...te_formulaire_qf_hubee_subscription_job.rb | 43 ++++++++ ...rmulaire_qf_hubee_subscription_job_spec.rb | 100 ++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 app/jobs/create_formulaire_qf_hubee_subscription_job.rb create mode 100644 spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb diff --git a/app/jobs/create_formulaire_qf_hubee_subscription_job.rb b/app/jobs/create_formulaire_qf_hubee_subscription_job.rb new file mode 100644 index 000000000..a74dcb2c1 --- /dev/null +++ b/app/jobs/create_formulaire_qf_hubee_subscription_job.rb @@ -0,0 +1,43 @@ +class CreateFormulaireQFHubEESubscriptionJob < ApplicationJob + def perform(authorization_request_id) + authorization_request = AuthorizationRequest.find(authorization_request_id) + + hubee_organization_payload = find_or_create_organization_on_hubee(authorization_request) + + authorization_request.extra_infos['hubee_organization_id'] = build_hubee_organization_id(hubee_organization_payload) + authorization_request.save! + + create_subscription_on_hubee(authorization_request, hubee_organization_payload) + rescue ActiveRecord::RecordNotFound + # do nothing + end + + private + + def find_or_create_organization_on_hubee(authorization_request) + hubee_api_client.find_organization(authorization_request.organization) + rescue HubEEAPIClient::NotFound + hubee_api_client.create_organization(authorization_request.organization, authorization_request.demandeur.email) + end + + def create_subscription_on_hubee(authorization_request, hubee_organization) + hubee_subscription_payload = hubee_api_client.create_subscription(authorization_request, hubee_organization, process_code) + + authorization_request.extra_infos['hubee_subscription_id'] = hubee_subscription_payload['id'] + authorization_request.save! + rescue HubEEAPIClient::AlreadyExists + # do nothing + end + + def build_hubee_organization_id(hubee_organization_payload) + "SI-#{hubee_organization_payload['companyRegister']}-#{hubee_organization_payload['branchCode']}" + end + + def process_code + 'FORMULAIRE_QF' + end + + def hubee_api_client + @hubee_api_client ||= HubEEAPIClient.new + end +end diff --git a/spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb b/spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb new file mode 100644 index 000000000..ad3984137 --- /dev/null +++ b/spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb @@ -0,0 +1,100 @@ +RSpec.describe CreateFormulaireQFHubEESubscriptionJob, type: :job do + describe '#perform' do + subject(:create_formulaire_qf_hubee_subscription_job) do + described_class.perform_now(authorization_request.id) + end + + let(:hubee_api_client) { instance_double(HubEEAPIClient) } + let(:authorization_request) { create(:authorization_request, :with_demandeur, api: 'particulier') } + let(:subscription_payload) { hubee_subscription_payload(authorization_request:) } + + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + end + + context 'when organization does not exist on HubEE' do + let(:organization_payload) { hubee_organization_payload(siret:, code_commune:) } + let(:siret) { '12345678901234' } + let(:code_commune) { '12345' } + + before do + allow(hubee_api_client).to receive(:find_organization).and_raise(HubEEAPIClient::NotFound) + allow(hubee_api_client).to receive_messages(create_organization: organization_payload, create_subscription: subscription_payload) + end + + it 'creates an organization on HubEE' do + expect(hubee_api_client).to receive(:create_organization) + + create_formulaire_qf_hubee_subscription_job + end + + it 'stores the organization id on the authorization request' do + create_formulaire_qf_hubee_subscription_job + + expect(authorization_request.reload.extra_infos['hubee_organization_id']).to eq("SI-#{siret}-#{code_commune}") + end + + it 'creates a subscription on HubEE' do + expect(hubee_api_client).to receive(:create_subscription) + + create_formulaire_qf_hubee_subscription_job + end + + it 'stores the subscription id on the authorization request' do + create_formulaire_qf_hubee_subscription_job + + expect(authorization_request.reload.extra_infos['hubee_subscription_id']).to eq(subscription_payload['id']) + end + end + + context 'when organization exists on HubEE' do + before do + allow(hubee_api_client).to receive_messages(find_organization: hubee_organization_payload, create_subscription: subscription_payload) + end + + it 'does not create an organization on HubEE' do + expect(hubee_api_client).not_to receive(:create_organization) + + create_formulaire_qf_hubee_subscription_job + end + + it 'creates a subscription on HubEE' do + expect(hubee_api_client).to receive(:create_subscription) + + create_formulaire_qf_hubee_subscription_job + end + + it 'stores the subscription id on the authorization request' do + create_formulaire_qf_hubee_subscription_job + + expect(authorization_request.reload.extra_infos['hubee_subscription_id']).to eq(subscription_payload['id']) + end + end + + describe 'subscription creation' do + before do + allow(hubee_api_client).to receive(:find_organization).and_return(hubee_organization_payload) + end + + context 'when subscription already exists' do + before do + allow(hubee_api_client).to receive(:create_subscription).and_raise(HubEEAPIClient::AlreadyExists) + end + + it 'does not raise an error' do + expect { create_formulaire_qf_hubee_subscription_job }.not_to raise_error + end + end + + context 'when subscription failed' do + before do + allow(hubee_api_client).to receive(:create_subscription).and_raise(Faraday::Error) + end + + it 'raises an error' do + expect { create_formulaire_qf_hubee_subscription_job }.to raise_error(Faraday::Error) + end + end + end + end +end From 5e096429f916e0592bf8dbe312fc2e0b2ec5f41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Mon, 24 Jun 2024 18:52:30 +0200 Subject: [PATCH 11/16] DatapassWebhook::APIParticulier handles formulaire QF HubEE subscription --- ...te_formulaire_qf_hubee_subscription_job.rb | 8 ++++ .../datapass_webhook/api_particulier.rb | 1 + .../v2/api_particulier_spec.rb | 44 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb diff --git a/app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb b/app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb new file mode 100644 index 000000000..4ebfc4213 --- /dev/null +++ b/app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb @@ -0,0 +1,8 @@ +class DatapassWebhook::ScheduleCreateFormulaireQFHubEESubscriptionJob < ApplicationInteractor + def call + return unless context.event == 'approve' + return unless context.modalities.include?('formulaire_qf') + + CreateFormulaireQFHubEESubscriptionJob.perform_later(context.authorization_request.id) + end +end diff --git a/app/organizers/datapass_webhook/api_particulier.rb b/app/organizers/datapass_webhook/api_particulier.rb index 0604b187d..a46faad56 100644 --- a/app/organizers/datapass_webhook/api_particulier.rb +++ b/app/organizers/datapass_webhook/api_particulier.rb @@ -19,6 +19,7 @@ class APIParticulier < ApplicationOrganizer ::DatapassWebhook::RefuseCurrentAuthorizationRequest, ::DatapassWebhook::RevokeCurrentToken, ::DatapassWebhook::UpdateMailjetContacts, + ::DatapassWebhook::ScheduleCreateFormulaireQFHubEESubscriptionJob, ::DatapassWebhook::ExtractMailjetVariables, ::DatapassWebhook::ScheduleAuthorizationRequestEmails, ::DatapassWebhook::APIParticulier::NotifyReporters diff --git a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb index ecc0e8d44..179e697f0 100644 --- a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb +++ b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb @@ -53,6 +53,50 @@ end end + describe 'modalities' do + context 'when modalities does not include formulaire_qf' do + before do + datapass_webhook_params['data']['data']['modalities'] = ['params'] + end + + it 'does not schedule a job to create formulaire qf access on HubEE' do + expect { + subject + }.not_to have_enqueued_job(CreateFormulaireQFHubEESubscriptionJob) + end + end + + context 'when modalities include formulaire_qf' do + before do + datapass_webhook_params['data']['data']['modalities'] = ['formulaire_qf'] + end + + context 'when event is approve' do + before do + datapass_webhook_params['event'] = 'approve' + end + + it 'schedules a job to create formulaire qf access on HubEE' do + expect { + subject + }.to have_enqueued_job(CreateFormulaireQFHubEESubscriptionJob) + end + end + + context 'when event not approve' do + before do + datapass_webhook_params['event'] = 'reject' + end + + it 'does not schedule a job to create formulaire qf access on HubEE' do + expect { + subject + }.not_to have_enqueued_job(CreateFormulaireQFHubEESubscriptionJob) + end + end + end + end + describe 'Mailjet adding contacts' do it 'adds contacts to Entreprise mailjet list' do expect(Mailjet::Contactslist_managemanycontacts).to receive(:create).with( From d8bffb60cecbea206391d7253d98cd83add271c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Thu, 27 Jun 2024 10:24:08 +0200 Subject: [PATCH 12/16] Remove useless module --- spec/rails_helper.rb | 1 - spec/support/fixtures_helpers.rb | 17 ----------------- 2 files changed, 18 deletions(-) delete mode 100644 spec/support/fixtures_helpers.rb diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 0ce2ebde0..2cee3272f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -84,7 +84,6 @@ config.include SpecsHelper config.include FeatureHelper, type: :feature config.include ExternalUrlHelper, type: :feature - config.include FixturesHelpers config.include INSEESireneAPIMocks config.include HubEEAPIMocks diff --git a/spec/support/fixtures_helpers.rb b/spec/support/fixtures_helpers.rb deleted file mode 100644 index 430021fe4..000000000 --- a/spec/support/fixtures_helpers.rb +++ /dev/null @@ -1,17 +0,0 @@ -module FixturesHelpers - def fixture_exists?(path) - Rails.root.join('spec', 'fixtures', path).exist? - end - - def open_fixture(path) - File.open(File.join(File.dirname(__FILE__), '..', 'fixtures', path)) - end - - def read_fixture(path) - open_fixture(path).read - end - - def read_json_fixture(path) - JSON.parse(open_fixture(path).read) - end -end From 87b770995b5427cf309ef08ea87e984e3a4fd11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Delmaire?= Date: Tue, 2 Jul 2024 16:39:16 +0200 Subject: [PATCH 13/16] Update HubEEAPIClient with latest specs --- app/clients/hubee_api_client.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/clients/hubee_api_client.rb b/app/clients/hubee_api_client.rb index 68424f930..111b09ab4 100644 --- a/app/clients/hubee_api_client.rb +++ b/app/clients/hubee_api_client.rb @@ -45,7 +45,12 @@ def create_subscription(authorization_request, organization_payload, process_cod status: 'Actif', localAdministrator: { email: authorization_request.demandeur.email - } + }, + delegationActor: { + branchCode: organization_payload['branchCode'], + companyRegister: organization_payload['companyRegister'], + type: 'EDT' + }, }.to_json, 'Content-Type' => 'application/json' ) From fdecdcc519f2cc1d9718c8c341f0ab509fb2a72e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Delmaire=20Lo=C3=AFc?= Date: Tue, 27 Aug 2024 15:02:37 +0200 Subject: [PATCH 14/16] Add valid process_code for Formulaire QF Co-authored-by: Jean-Baptiste Feldis <5403+jbfeldis@users.noreply.github.com> --- app/jobs/create_formulaire_qf_hubee_subscription_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/create_formulaire_qf_hubee_subscription_job.rb b/app/jobs/create_formulaire_qf_hubee_subscription_job.rb index a74dcb2c1..f7ae2426f 100644 --- a/app/jobs/create_formulaire_qf_hubee_subscription_job.rb +++ b/app/jobs/create_formulaire_qf_hubee_subscription_job.rb @@ -34,7 +34,7 @@ def build_hubee_organization_id(hubee_organization_payload) end def process_code - 'FORMULAIRE_QF' + 'FormulaireQF' end def hubee_api_client From 62f9b90687ee281bbe849c2b0ec7e44a28da7ef6 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Feldis <5403+jbfeldis@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:38:17 +0200 Subject: [PATCH 15/16] =?UTF-8?q?Active=20l'abonnement=20HubEE=20et=20ajou?= =?UTF-8?q?te=20la=20collectivit=C3=A9=20sur=20FQF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les abonnements HubEE doivent être créées avant d'être activés, ce commit met en place cette séparation. Pour associer un éditeur le webhook envoie maintenant le service_provider associé à la demande (stocké dans extra_infos). Une méthode pour récupérer un abonnement existant a aussi été ajoutée pour rendre le webhook plus robuste. La collectivité est aussi créée du côté du FormulaireQF. --- Gemfile | 6 +- Gemfile.lock | 8 ++ app/clients/abstract_hubee_api_client.rb | 2 +- app/clients/formulaire_qf_api_client.rb | 32 ++++++ app/clients/hubee_api_authentication.rb | 7 ++ app/clients/hubee_api_client.rb | 104 +++++++++++++----- .../datapass_webhook/adapt_v2_to_v1.rb | 3 +- .../create_formulaire_qf_collectivity.rb | 14 +++ .../create_hubee_organization.rb | 27 +++++ .../create_hubee_subscription.rb | 52 +++++++++ .../find_or_create_authorization_request.rb | 9 +- ...te_formulaire_qf_hubee_subscription_job.rb | 8 -- ...dule_create_formulaire_qf_resources_job.rb | 8 ++ ...te_formulaire_qf_hubee_subscription_job.rb | 43 -------- .../create_formulaire_qf_resources_job.rb | 7 ++ .../datapass_webhook/api_particulier.rb | 2 +- .../create_formulaire_qf_resources.rb | 18 +++ config/credentials/sandbox.yml.enc | 2 +- config/credentials/staging.yml.enc | 2 +- config/credentials/test.yml.enc | 2 +- spec/factories/datapass_webhooks.rb | 9 ++ .../create_formulaire_qf_collectivity_spec.rb | 25 +++++ .../create_hubee_organization_spec.rb | 47 ++++++++ .../create_hubee_subscription_spec.rb | 82 ++++++++++++++ ...nd_or_create_authorization_request_spec.rb | 4 + ...rmulaire_qf_hubee_subscription_job_spec.rb | 100 ----------------- .../create_formulaire_qf_resources_spec.rb | 68 ++++++++++++ .../v2/api_particulier_spec.rb | 12 +- spec/support/insee_sirene_api_mocks.rb | 4 + 29 files changed, 514 insertions(+), 193 deletions(-) create mode 100644 app/clients/formulaire_qf_api_client.rb create mode 100644 app/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity.rb create mode 100644 app/interactors/datapass_webhook/api_particulier/create_hubee_organization.rb create mode 100644 app/interactors/datapass_webhook/api_particulier/create_hubee_subscription.rb delete mode 100644 app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb create mode 100644 app/interactors/datapass_webhook/schedule_create_formulaire_qf_resources_job.rb delete mode 100644 app/jobs/create_formulaire_qf_hubee_subscription_job.rb create mode 100644 app/jobs/create_formulaire_qf_resources_job.rb create mode 100644 app/organizers/datapass_webhook/create_formulaire_qf_resources.rb create mode 100644 spec/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity_spec.rb create mode 100644 spec/interactors/datapass_webhook/api_particulier/create_hubee_organization_spec.rb create mode 100644 spec/interactors/datapass_webhook/api_particulier/create_hubee_subscription_spec.rb delete mode 100644 spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb create mode 100644 spec/organizers/datapass_webhook/create_formulaire_qf_resources_spec.rb diff --git a/Gemfile b/Gemfile index 9b973cc9f..6183661a7 100644 --- a/Gemfile +++ b/Gemfile @@ -78,8 +78,10 @@ gem 'wicked' gem 'rest-client' gem 'faraday' +gem 'faraday-gzip' gem 'faraday-net_http' gem 'faraday-retry' +gem 'faraday-encoding' group :development, :test do gem 'awesome_print' @@ -104,10 +106,10 @@ group :development do # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md gem 'rack-mini-profiler', '~> 3.3' gem 'rubocop', require: false - gem 'rubocop-rails' - gem 'rubocop-rspec' gem 'rubocop-capybara' gem 'rubocop-factory_bot' + gem 'rubocop-rails' + gem 'rubocop-rspec' gem 'rubocop-rspec_rails' gem 'better_errors' diff --git a/Gemfile.lock b/Gemfile.lock index 0b6d5c2f5..7c60799c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -157,6 +157,11 @@ GEM faraday-net_http (>= 2.0, < 3.4) json logger + faraday-encoding (0.0.6) + faraday + faraday-gzip (2.0.1) + faraday (>= 1.0) + zlib (~> 3.0) faraday-net_http (3.3.0) net-http faraday-net_http_persistent (2.3.0) @@ -563,6 +568,7 @@ GEM nokogiri (~> 1.8) yajl-ruby (1.4.3) zeitwerk (2.7.1) + zlib (3.1.1) PLATFORMS aarch64-linux @@ -588,6 +594,8 @@ DEPENDENCIES draper factory_bot_rails faraday + faraday-encoding + faraday-gzip faraday-net_http faraday-retry gaffe diff --git a/app/clients/abstract_hubee_api_client.rb b/app/clients/abstract_hubee_api_client.rb index 934b0e481..9081c04aa 100644 --- a/app/clients/abstract_hubee_api_client.rb +++ b/app/clients/abstract_hubee_api_client.rb @@ -4,7 +4,7 @@ class AbstractHubEEAPIClient protected def http_connection(&block) - @http_connection ||= Faraday.new do |conn| + Faraday.new do |conn| conn.request :retry, max: 5 conn.response :raise_error conn.response :json diff --git a/app/clients/formulaire_qf_api_client.rb b/app/clients/formulaire_qf_api_client.rb new file mode 100644 index 000000000..a9ac73c1b --- /dev/null +++ b/app/clients/formulaire_qf_api_client.rb @@ -0,0 +1,32 @@ +class FormulaireQFAPIClient + def create_collectivity(organization:, editor_id: nil) + params = { + siret: organization.siret, + code_cog: organization.code_commune_etablissement, + departement: organization.code_postal_etablissement[0..1], + name: organization.denomination, + status: 'active', + editor: editor_id + } + + http_connection.post("#{host}/api/collectivites", params.to_json) + end + + private + + def host + Rails.application.credentials.formulaire_qf.host + end + + def http_connection(&block) + Faraday.new do |conn| + conn.headers['Content-Type'] = 'application/json' + conn.request :authorization, 'Bearer', -> { secret } + yield(conn) if block + end + end + + def secret + Rails.application.credentials.formulaire_qf.secret + end +end diff --git a/app/clients/hubee_api_authentication.rb b/app/clients/hubee_api_authentication.rb index 953068b63..76db47095 100644 --- a/app/clients/hubee_api_authentication.rb +++ b/app/clients/hubee_api_authentication.rb @@ -18,4 +18,11 @@ def auth_url def encoded_client_id_and_secret Base64.strict_encode64("#{consumer_key}:#{consumer_secret}") end + + def http_connection(&block) + @http_connection ||= super do |conn| + conn.response :json + yield(conn) if block + end + end end diff --git a/app/clients/hubee_api_client.rb b/app/clients/hubee_api_client.rb index 111b09ab4..a85c2d044 100644 --- a/app/clients/hubee_api_client.rb +++ b/app/clients/hubee_api_client.rb @@ -1,7 +1,13 @@ -class HubEEAPIClient < AbstractHubEEAPIClient +class HubEEAPIClient < AbstractHubEEAPIClient # rubocop:disable Metrics/ClassLength class NotFound < StandardError; end class AlreadyExists < StandardError; end + def find_or_create_organization(organization, email_demandeur = nil) + find_organization(organization) + rescue NotFound + create_organization(organization, email_demandeur) + end + def find_organization(organization) http_connection.get("#{host}/referential/v1/organizations/SI-#{organization.siret}-#{organization.code_commune_etablissement}").body rescue Faraday::ResourceNotFound @@ -17,24 +23,83 @@ def create_organization(organization, email) branchCode: organization.code_commune_etablissement, email:, name: organization.denomination, + country: 'France', postalCode: organization.code_postal_etablissement, territory: organization.code_commune_etablissement, status: 'Actif' }.to_json, 'Content-Type' => 'application/json' - ) + ).body rescue Faraday::BadRequestError => e raise AlreadyExists if already_exists_error?(e) raise end - def create_subscription(authorization_request, organization_payload, process_code) + def create_subscription(authorization_request, organization_payload, process_code, editor_payload = {}) + subscription_payload = find_or_create_inactive_subscription(authorization_request, organization_payload, process_code) + activate_subscription(authorization_request, subscription_payload, editor_payload) + subscription_payload + end + + def find_subscription(_authorization_request, organization_payload, process_code) + request = http_connection { |conn| conn.request :gzip }.get( + "#{host}/referential/v1/subscriptions", + companyRegister: organization_payload['companyRegister'], + processCode: process_code + ) + request.body.first + end + + protected + + def host + Rails.application.credentials.hubee_api_url + end + + def already_exists_error?(faraday_error) + faraday_error.response[:body]['errors'].any? do |error| + error['message'].include?('already exists') + end + end + + def http_connection(&block) + super do |conn| + conn.request :authorization, 'Bearer', -> { HubEEAPIAuthentication.new.access_token } + yield(conn) if block + end + end + + private + + def activate_subscription(authorization_request, subscription_payload, editor_payload = {}) # rubocop:disable Metrics/AbcSize + subscription_id = authorization_request.extra_infos['hubee_subscription_id'] + return if subscription_id.blank? + + payload = subscription_payload.with_indifferent_access.merge({ + status: 'Actif', + activateDateTime: DateTime.now.iso8601, + accessMode: 'API', + notificationFrequency: 'Aucune' + }.with_indifferent_access) + + payload.delete('id') + payload.delete('creationDateTime') + payload.merge!(editor_payload.with_indifferent_access) + + http_connection.put( + "#{host}/referential/v1/subscriptions/#{subscription_id}", + payload.to_json, + 'Content-Type' => 'application/json' + ).body + end + + def create_inactive_subscription(authorization_request, organization_payload, process_code) # rubocop:disable Metrics/AbcSize http_connection.post( "#{host}/referential/v1/subscriptions", { datapassId: authorization_request.external_id.to_i, - notificationFrequency: 'unitaire', + notificationFrequency: 'Aucune', processCode: process_code, subscriber: { type: 'SI', @@ -42,39 +107,24 @@ def create_subscription(authorization_request, organization_payload, process_cod branchCode: organization_payload['branchCode'] }, email: authorization_request.demandeur.email, - status: 'Actif', + status: 'Inactif', localAdministrator: { email: authorization_request.demandeur.email }, - delegationActor: { - branchCode: organization_payload['branchCode'], - companyRegister: organization_payload['companyRegister'], - type: 'EDT' - }, + validateDateTime: DateTime.now.iso8601, + updateDateTime: DateTime.now.iso8601 }.to_json, 'Content-Type' => 'application/json' - ) + ).body rescue Faraday::BadRequestError => e raise AlreadyExists if already_exists_error?(e) raise end - protected - - def host - Rails.application.credentials.hubee_api_url - end - - def already_exists_error?(faraday_error) - faraday_error.response[:body]['errors'].any? do |error| - error['message'].include?('already exists') - end - end - - def http_connection - super do |conn| - conn.request :authorization, 'Bearer', -> { HubEEAPIAuthentication.new.access_token } - end + def find_or_create_inactive_subscription(authorization_request, organization_payload, process_code) + create_inactive_subscription(authorization_request, organization_payload, process_code) + rescue HubEEAPIClient::AlreadyExists + find_subscription(authorization_request, organization_payload, process_code) end end diff --git a/app/interactors/datapass_webhook/adapt_v2_to_v1.rb b/app/interactors/datapass_webhook/adapt_v2_to_v1.rb index d5d3139c8..3130b36e8 100644 --- a/app/interactors/datapass_webhook/adapt_v2_to_v1.rb +++ b/app/interactors/datapass_webhook/adapt_v2_to_v1.rb @@ -22,7 +22,8 @@ def build_data 'previous_enrollment_id' => nil, 'scopes' => generic_data['scopes'].index_with { |_scope| true }, 'team_members' => build_team_members, - 'events' => [] + 'events' => [], + 'service_provider' => context.data['service_provider'] } } end diff --git a/app/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity.rb b/app/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity.rb new file mode 100644 index 000000000..c2c3600c2 --- /dev/null +++ b/app/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity.rb @@ -0,0 +1,14 @@ +class DatapassWebhook::APIParticulier::CreateFormulaireQFCollectivity < ApplicationInteractor + delegate :authorization_request, to: :context + delegate :organization, to: :authorization_request, private: true + + def call + FormulaireQFAPIClient.new.create_collectivity(organization:, editor_id:) + end + + private + + def editor_id + authorization_request.extra_infos.dig('service_provider', 'id') + end +end diff --git a/app/interactors/datapass_webhook/api_particulier/create_hubee_organization.rb b/app/interactors/datapass_webhook/api_particulier/create_hubee_organization.rb new file mode 100644 index 000000000..0cda5568d --- /dev/null +++ b/app/interactors/datapass_webhook/api_particulier/create_hubee_organization.rb @@ -0,0 +1,27 @@ +class DatapassWebhook::APIParticulier::CreateHubEEOrganization < ApplicationInteractor + delegate :authorization_request, :hubee_organization_payload, to: :context + + def call + context.hubee_organization_payload = find_or_create_organization_on_hubee + save_hubee_organization_id_to_authorization_request + end + + private + + def build_hubee_organization_id + "SI-#{hubee_organization_payload['companyRegister']}-#{hubee_organization_payload['branchCode']}" + end + + def find_or_create_organization_on_hubee + hubee_api_client.find_or_create_organization(authorization_request.organization, authorization_request.demandeur.email) + end + + def hubee_api_client + @hubee_api_client ||= HubEEAPIClient.new + end + + def save_hubee_organization_id_to_authorization_request + authorization_request.extra_infos['hubee_organization_id'] = build_hubee_organization_id + authorization_request.save! + end +end diff --git a/app/interactors/datapass_webhook/api_particulier/create_hubee_subscription.rb b/app/interactors/datapass_webhook/api_particulier/create_hubee_subscription.rb new file mode 100644 index 000000000..86779ed05 --- /dev/null +++ b/app/interactors/datapass_webhook/api_particulier/create_hubee_subscription.rb @@ -0,0 +1,52 @@ +class DatapassWebhook::APIParticulier::CreateHubEESubscription < ApplicationInteractor + delegate :authorization_request, :hubee_organization_payload, :hubee_subscription_payload, to: :context + + def call + context.hubee_subscription_payload = create_subscription_on_hubee + save_hubee_subscription_id_to_authorization_request + end + + private + + def create_subscription_on_hubee + hubee_api_client.create_subscription(authorization_request, hubee_organization_payload, process_code, editor_payload) + end + + def editor_organization + @editor_organization ||= Organization.new(service_provider['siret']) + end + + def editor_payload + return {} unless editor_subscription? + + { + delegationActor: { + branchCode: editor_organization.code_commune_etablissement, + companyRegister: editor_organization.siret, + type: 'EDT' + }, + accessMode: 'API' + } + end + + def editor_subscription? + service_provider['type'] == 'editor' + end + + def hubee_api_client + @hubee_api_client ||= HubEEAPIClient.new + end + + def process_code + 'FormulaireQF' + end + + def save_hubee_subscription_id_to_authorization_request + authorization_request.extra_infos['hubee_subscription_id'] = hubee_subscription_payload['id'] + authorization_request.save! + end + + def service_provider + @service_provider ||= Hash(authorization_request.extra_infos['service_provider']) + end +end diff --git a/app/interactors/datapass_webhook/find_or_create_authorization_request.rb b/app/interactors/datapass_webhook/find_or_create_authorization_request.rb index c8c7ef392..3c968ec07 100644 --- a/app/interactors/datapass_webhook/find_or_create_authorization_request.rb +++ b/app/interactors/datapass_webhook/find_or_create_authorization_request.rb @@ -83,10 +83,17 @@ def authorization_request_attributes ).merge(authorization_request_attributes_for_current_event).merge( 'last_update' => fired_at_as_datetime, 'previous_external_id' => context.data['pass']['copied_from_enrollment_id'], - 'api' => context.api + 'api' => context.api, + 'extra_infos' => extra_infos_with_service_provider ) end + def extra_infos_with_service_provider + context.authorization_request.extra_infos.merge({ + 'service_provider' => Hash(context.data.dig('pass', 'service_provider')) + }) + end + def authorization_request_attributes_for_current_event authorization_request_attributes_for_current_event = {} diff --git a/app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb b/app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb deleted file mode 100644 index 4ebfc4213..000000000 --- a/app/interactors/datapass_webhook/schedule_create_formulaire_qf_hubee_subscription_job.rb +++ /dev/null @@ -1,8 +0,0 @@ -class DatapassWebhook::ScheduleCreateFormulaireQFHubEESubscriptionJob < ApplicationInteractor - def call - return unless context.event == 'approve' - return unless context.modalities.include?('formulaire_qf') - - CreateFormulaireQFHubEESubscriptionJob.perform_later(context.authorization_request.id) - end -end diff --git a/app/interactors/datapass_webhook/schedule_create_formulaire_qf_resources_job.rb b/app/interactors/datapass_webhook/schedule_create_formulaire_qf_resources_job.rb new file mode 100644 index 000000000..d566d84ac --- /dev/null +++ b/app/interactors/datapass_webhook/schedule_create_formulaire_qf_resources_job.rb @@ -0,0 +1,8 @@ +class DatapassWebhook::ScheduleCreateFormulaireQFResourcesJob < ApplicationInteractor + def call + return unless context.event == 'approve' + return unless context.modalities.include?('formulaire_qf') + + CreateFormulaireQFResourcesJob.perform_later(context.authorization_request.id) + end +end diff --git a/app/jobs/create_formulaire_qf_hubee_subscription_job.rb b/app/jobs/create_formulaire_qf_hubee_subscription_job.rb deleted file mode 100644 index f7ae2426f..000000000 --- a/app/jobs/create_formulaire_qf_hubee_subscription_job.rb +++ /dev/null @@ -1,43 +0,0 @@ -class CreateFormulaireQFHubEESubscriptionJob < ApplicationJob - def perform(authorization_request_id) - authorization_request = AuthorizationRequest.find(authorization_request_id) - - hubee_organization_payload = find_or_create_organization_on_hubee(authorization_request) - - authorization_request.extra_infos['hubee_organization_id'] = build_hubee_organization_id(hubee_organization_payload) - authorization_request.save! - - create_subscription_on_hubee(authorization_request, hubee_organization_payload) - rescue ActiveRecord::RecordNotFound - # do nothing - end - - private - - def find_or_create_organization_on_hubee(authorization_request) - hubee_api_client.find_organization(authorization_request.organization) - rescue HubEEAPIClient::NotFound - hubee_api_client.create_organization(authorization_request.organization, authorization_request.demandeur.email) - end - - def create_subscription_on_hubee(authorization_request, hubee_organization) - hubee_subscription_payload = hubee_api_client.create_subscription(authorization_request, hubee_organization, process_code) - - authorization_request.extra_infos['hubee_subscription_id'] = hubee_subscription_payload['id'] - authorization_request.save! - rescue HubEEAPIClient::AlreadyExists - # do nothing - end - - def build_hubee_organization_id(hubee_organization_payload) - "SI-#{hubee_organization_payload['companyRegister']}-#{hubee_organization_payload['branchCode']}" - end - - def process_code - 'FormulaireQF' - end - - def hubee_api_client - @hubee_api_client ||= HubEEAPIClient.new - end -end diff --git a/app/jobs/create_formulaire_qf_resources_job.rb b/app/jobs/create_formulaire_qf_resources_job.rb new file mode 100644 index 000000000..b60c13883 --- /dev/null +++ b/app/jobs/create_formulaire_qf_resources_job.rb @@ -0,0 +1,7 @@ +class CreateFormulaireQFResourcesJob < ApplicationJob + def perform(authorization_request_id) + authorization_request = AuthorizationRequest.find(authorization_request_id) + + DatapassWebhook::CreateFormulaireQFResources.call(authorization_request:) + end +end diff --git a/app/organizers/datapass_webhook/api_particulier.rb b/app/organizers/datapass_webhook/api_particulier.rb index a46faad56..f5328703c 100644 --- a/app/organizers/datapass_webhook/api_particulier.rb +++ b/app/organizers/datapass_webhook/api_particulier.rb @@ -19,7 +19,7 @@ class APIParticulier < ApplicationOrganizer ::DatapassWebhook::RefuseCurrentAuthorizationRequest, ::DatapassWebhook::RevokeCurrentToken, ::DatapassWebhook::UpdateMailjetContacts, - ::DatapassWebhook::ScheduleCreateFormulaireQFHubEESubscriptionJob, + ::DatapassWebhook::ScheduleCreateFormulaireQFResourcesJob, ::DatapassWebhook::ExtractMailjetVariables, ::DatapassWebhook::ScheduleAuthorizationRequestEmails, ::DatapassWebhook::APIParticulier::NotifyReporters diff --git a/app/organizers/datapass_webhook/create_formulaire_qf_resources.rb b/app/organizers/datapass_webhook/create_formulaire_qf_resources.rb new file mode 100644 index 000000000..3d26751cb --- /dev/null +++ b/app/organizers/datapass_webhook/create_formulaire_qf_resources.rb @@ -0,0 +1,18 @@ +class DatapassWebhook::CreateFormulaireQFResources < ApplicationOrganizer + organize DatapassWebhook::APIParticulier::CreateHubEEOrganization, + DatapassWebhook::APIParticulier::CreateHubEESubscription, + DatapassWebhook::APIParticulier::CreateFormulaireQFCollectivity + + around do |interactor| + interactor.call + rescue StandardError => e + Sentry.set_context( + 'DataPass webhook: create FormulaireQF resources', + payload: { + authorization_request_id: context.authorization_request.id + } + ) + + Sentry.capture_exception(e) + end +end diff --git a/config/credentials/sandbox.yml.enc b/config/credentials/sandbox.yml.enc index 92e621b3b..72a5512a2 100644 --- a/config/credentials/sandbox.yml.enc +++ b/config/credentials/sandbox.yml.enc @@ -1 +1 @@ -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--sVa2IBBRCHcz0YkY--KqKofsqRXSMfN0XY3PEkxw== \ No newline at end of file +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--pR1hfy5qn2BKDerm--YWGU6sMyb9WOczKW30enzA== \ No newline at end of file diff --git a/config/credentials/staging.yml.enc b/config/credentials/staging.yml.enc index 3524d000d..c9aedb5a2 100644 --- a/config/credentials/staging.yml.enc +++ b/config/credentials/staging.yml.enc @@ -1 +1 @@ -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--XsN3Zq365PlsbdKl--Mxes8FOFobS+b+Yx+Ky+Lg== \ No newline at end of file +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--3vwK8dvGCDo4Bq3H--IREQaAm34LMx0SQuHy1fVw== \ No newline at end of file diff --git a/config/credentials/test.yml.enc b/config/credentials/test.yml.enc index 4400b7321..26ec8c3a3 100644 --- a/config/credentials/test.yml.enc +++ b/config/credentials/test.yml.enc @@ -1 +1 @@ -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--dzjtM4Kf2fi6YpMd--1x7ObL5qvU6eia9C3p7sjA== \ No newline at end of file +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--1iVrN2uZYhSZST7Q--wTX5GsuCHbFXF8Ki2bYStA== \ No newline at end of file diff --git a/spec/factories/datapass_webhooks.rb b/spec/factories/datapass_webhooks.rb index b574ba846..cd813e636 100644 --- a/spec/factories/datapass_webhooks.rb +++ b/spec/factories/datapass_webhooks.rb @@ -63,6 +63,15 @@ 'entreprises' => true } end + + service_provider do + { + 'id' => '3d_ouest', + 'type' => 'editor', + 'siret' => '44973625500018', + 'code' => '22113' + } + end end factory :datapass_webhook_team_member_model, class: Hash do diff --git a/spec/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity_spec.rb b/spec/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity_spec.rb new file mode 100644 index 000000000..024c08c3a --- /dev/null +++ b/spec/interactors/datapass_webhook/api_particulier/create_formulaire_qf_collectivity_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::APIParticulier::CreateFormulaireQFCollectivity, type: :interactor do + subject(:interactor) { described_class.call(**params) } + + let(:authorization_request) { create(:authorization_request) } + let(:formulaire_qf_api_client) { instance_double(FormulaireQFAPIClient) } + let(:params) { { authorization_request: } } + let(:organization) { authorization_request.organization } + let(:editor_id) { 'SUPEREDITOR' } + + before do + allow(FormulaireQFAPIClient).to receive(:new).and_return(formulaire_qf_api_client) + allow(formulaire_qf_api_client).to receive(:create_collectivity) + + authorization_request.extra_infos['service_provider'] = { 'id' => editor_id } + end + + it 'creates a collectivity on FormulaireQF' do + expect(formulaire_qf_api_client).to receive(:create_collectivity).with(organization:, editor_id:) + interactor + end + + it { is_expected.to be_a_success } +end diff --git a/spec/interactors/datapass_webhook/api_particulier/create_hubee_organization_spec.rb b/spec/interactors/datapass_webhook/api_particulier/create_hubee_organization_spec.rb new file mode 100644 index 000000000..927367197 --- /dev/null +++ b/spec/interactors/datapass_webhook/api_particulier/create_hubee_organization_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::APIParticulier::CreateHubEEOrganization, type: :interactor do + subject(:interactor) { described_class.call(**params) } + + let(:authorization_request) { create(:authorization_request, :with_demandeur) } + let(:hubee_api_client) { instance_double(HubEEAPIClient) } + let(:params) { { authorization_request: } } + let(:stripped_organization_payload) { { 'companyRegister' => '123456789', 'branchCode' => '123456' } } + + context 'when everything works as expected' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:find_or_create_organization).and_return(stripped_organization_payload) + end + + it 'finds or creates an HubEE organization' do + expect(hubee_api_client).to receive(:find_or_create_organization).with(authorization_request.organization, authorization_request.demandeur.email) + interactor + end + + it 'saves the HubEE organization id to the authorization request' do + expect { + interactor + }.to change { authorization_request.reload.extra_infos['hubee_organization_id'] }.from(nil).to('SI-123456789-123456') + end + + it 'adds the HubEE organization payload to the context' do + expect(interactor.hubee_organization_payload).to eq(stripped_organization_payload) + end + + it { is_expected.to be_a_success } + end + + context 'when HubEE raises an error' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:find_or_create_organization).and_raise(Faraday::BadRequestError) + end + + it 'raises an error' do + expect { + interactor + }.to raise_error(Faraday::BadRequestError) + end + end +end diff --git a/spec/interactors/datapass_webhook/api_particulier/create_hubee_subscription_spec.rb b/spec/interactors/datapass_webhook/api_particulier/create_hubee_subscription_spec.rb new file mode 100644 index 000000000..c8e78269f --- /dev/null +++ b/spec/interactors/datapass_webhook/api_particulier/create_hubee_subscription_spec.rb @@ -0,0 +1,82 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::APIParticulier::CreateHubEESubscription, type: :interactor do + subject(:interactor) { described_class.call(**params) } + + let(:authorization_request) { create(:authorization_request) } + let(:hubee_api_client) { instance_double(HubEEAPIClient) } + let(:stripped_hubee_organization_payload) { { 'branchCode' => '132456', 'companyRegister' => '123456789', 'id' => '123456789' } } + let(:stripped_hubee_subscription_payload) { { 'id' => 'ABC123456789' } } + let(:params) { { authorization_request:, hubee_organization_payload: stripped_hubee_organization_payload } } + + context 'when everything works as expected' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:create_subscription).and_return(stripped_hubee_subscription_payload) + end + + context 'when the authorization request has a service provider' do + let(:authorization_request) { create(:authorization_request, extra_infos: { 'service_provider' => service_provider }) } + let(:editor_siret) { '13002526500013' } + let(:service_provider) { { 'type' => 'editor', 'siret' => editor_siret } } + + context 'when the service provider is an editor' do + let(:insee_api_authentication) { instance_double(INSEEAPIAuthentication, access_token: 'access_token') } + let(:insee_payload) { insee_sirene_api_etablissement_valid_payload(siret: editor_siret, full: true) } + + before do + allow(INSEEAPIAuthentication).to receive(:new).and_return(insee_api_authentication) + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{editor_siret}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: insee_payload.to_json + ) + end + + it 'creates a subscription on HubEE with the editor payload' do + expect(hubee_api_client).to receive(:create_subscription).with(authorization_request, stripped_hubee_organization_payload, 'FormulaireQF', { delegationActor: { branchCode: '75107', companyRegister: '13002526500013', type: 'EDT' }, accessMode: 'API' }) + interactor + end + end + + context 'when the service provider is not an editor' do + let(:service_provider) { { 'type' => 'service', 'siret' => '123456' } } + + it 'creates a subscription on HubEE without the editor payload' do + expect(hubee_api_client).to receive(:create_subscription).with(authorization_request, stripped_hubee_organization_payload, 'FormulaireQF', {}) + interactor + end + end + end + + context 'when the authorization request does not have a service provider' do + it 'creates a subscription on HubEE' do + expect(hubee_api_client).to receive(:create_subscription).with(authorization_request, stripped_hubee_organization_payload, 'FormulaireQF', {}) + interactor + end + end + + it 'saves the HubEE subscription id to the authorization request' do + expect { + interactor + }.to change { authorization_request.reload.extra_infos['hubee_subscription_id'] }.from(nil).to('ABC123456789') + end + + it 'adds the HubEE subscription payload to the context' do + expect(interactor.hubee_subscription_payload).to eq(stripped_hubee_subscription_payload) + end + + it { is_expected.to be_a_success } + end + + context 'when HubEE raises an error' do + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive(:create_subscription).and_raise(Faraday::BadRequestError) + end + + it 'raises an error' do + expect { interactor }.to raise_error(Faraday::BadRequestError) + end + end +end diff --git a/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb b/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb index 9b7854ebf..14f33d553 100644 --- a/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb +++ b/spec/interactors/datapass_webhook/find_or_create_authorization_request_spec.rb @@ -68,6 +68,10 @@ expect(subject.reopening).to be_falsey end + it 'stores the service provider in extra_infos' do + expect { subject }.to change { authorization_request.reload.extra_infos['service_provider'] } + end + context 'when it is the same demandeur' do let(:demandeur) { build(:datapass_webhook_team_member_model, type: 'demandeur', email: authorization_request.demandeur.email) } diff --git a/spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb b/spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb deleted file mode 100644 index ad3984137..000000000 --- a/spec/jobs/create_formulaire_qf_hubee_subscription_job_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -RSpec.describe CreateFormulaireQFHubEESubscriptionJob, type: :job do - describe '#perform' do - subject(:create_formulaire_qf_hubee_subscription_job) do - described_class.perform_now(authorization_request.id) - end - - let(:hubee_api_client) { instance_double(HubEEAPIClient) } - let(:authorization_request) { create(:authorization_request, :with_demandeur, api: 'particulier') } - let(:subscription_payload) { hubee_subscription_payload(authorization_request:) } - - before do - allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) - end - - context 'when organization does not exist on HubEE' do - let(:organization_payload) { hubee_organization_payload(siret:, code_commune:) } - let(:siret) { '12345678901234' } - let(:code_commune) { '12345' } - - before do - allow(hubee_api_client).to receive(:find_organization).and_raise(HubEEAPIClient::NotFound) - allow(hubee_api_client).to receive_messages(create_organization: organization_payload, create_subscription: subscription_payload) - end - - it 'creates an organization on HubEE' do - expect(hubee_api_client).to receive(:create_organization) - - create_formulaire_qf_hubee_subscription_job - end - - it 'stores the organization id on the authorization request' do - create_formulaire_qf_hubee_subscription_job - - expect(authorization_request.reload.extra_infos['hubee_organization_id']).to eq("SI-#{siret}-#{code_commune}") - end - - it 'creates a subscription on HubEE' do - expect(hubee_api_client).to receive(:create_subscription) - - create_formulaire_qf_hubee_subscription_job - end - - it 'stores the subscription id on the authorization request' do - create_formulaire_qf_hubee_subscription_job - - expect(authorization_request.reload.extra_infos['hubee_subscription_id']).to eq(subscription_payload['id']) - end - end - - context 'when organization exists on HubEE' do - before do - allow(hubee_api_client).to receive_messages(find_organization: hubee_organization_payload, create_subscription: subscription_payload) - end - - it 'does not create an organization on HubEE' do - expect(hubee_api_client).not_to receive(:create_organization) - - create_formulaire_qf_hubee_subscription_job - end - - it 'creates a subscription on HubEE' do - expect(hubee_api_client).to receive(:create_subscription) - - create_formulaire_qf_hubee_subscription_job - end - - it 'stores the subscription id on the authorization request' do - create_formulaire_qf_hubee_subscription_job - - expect(authorization_request.reload.extra_infos['hubee_subscription_id']).to eq(subscription_payload['id']) - end - end - - describe 'subscription creation' do - before do - allow(hubee_api_client).to receive(:find_organization).and_return(hubee_organization_payload) - end - - context 'when subscription already exists' do - before do - allow(hubee_api_client).to receive(:create_subscription).and_raise(HubEEAPIClient::AlreadyExists) - end - - it 'does not raise an error' do - expect { create_formulaire_qf_hubee_subscription_job }.not_to raise_error - end - end - - context 'when subscription failed' do - before do - allow(hubee_api_client).to receive(:create_subscription).and_raise(Faraday::Error) - end - - it 'raises an error' do - expect { create_formulaire_qf_hubee_subscription_job }.to raise_error(Faraday::Error) - end - end - end - end -end diff --git a/spec/organizers/datapass_webhook/create_formulaire_qf_resources_spec.rb b/spec/organizers/datapass_webhook/create_formulaire_qf_resources_spec.rb new file mode 100644 index 000000000..99669ea98 --- /dev/null +++ b/spec/organizers/datapass_webhook/create_formulaire_qf_resources_spec.rb @@ -0,0 +1,68 @@ +require 'rails_helper' + +RSpec.describe DatapassWebhook::CreateFormulaireQFResources do + subject(:interactor) { described_class.call(authorization_request:) } + + let(:hubee_api_client) { instance_double(HubEEAPIClient) } + let(:insee_api_authentication) { instance_double(INSEEAPIAuthentication, access_token: 'access_token') } + let(:insee_payload) { insee_sirene_api_etablissement_valid_payload(siret: editor_siret, full: true) } + let(:authorization_request) { create(:authorization_request, :with_demandeur, api: 'particulier') } + let(:subscription_payload) { hubee_subscription_payload(authorization_request:) } + let(:editor_siret) { '13002526500013' } + let(:service_provider) { { 'type' => 'editor', 'siret' => editor_siret } } + let(:formulaire_qf_api_client) { instance_double(FormulaireQFAPIClient) } + let(:siret) { '12345678901234' } + let(:code_commune) { '12345' } + + let(:organization_payload) { hubee_organization_payload(siret:, code_commune:) } + + before do + allow(HubEEAPIClient).to receive(:new).and_return(hubee_api_client) + allow(hubee_api_client).to receive_messages(find_or_create_organization: organization_payload, create_subscription: subscription_payload) + allow(INSEEAPIAuthentication).to receive(:new).and_return(insee_api_authentication) + stub_request(:get, "https://api.insee.fr/entreprises/sirene/V3.11/siret/#{editor_siret}").to_return( + status: 200, + headers: { 'Content-Type' => 'application/json' }, + body: insee_payload.to_json + ) + allow(FormulaireQFAPIClient).to receive(:new).and_return(formulaire_qf_api_client) + allow(formulaire_qf_api_client).to receive(:create_collectivity) + end + + it 'stores the organization id on the authorization request' do + interactor + + expect(authorization_request.reload.extra_infos['hubee_organization_id']).to eq("SI-#{siret}-#{code_commune}") + end + + it 'creates a subscription on HubEE' do + expect(hubee_api_client).to receive(:create_subscription) + + interactor + end + + it 'stores the subscription id on the authorization request' do + interactor + + expect(authorization_request.reload.extra_infos['hubee_subscription_id']).to eq(subscription_payload['id']) + end + + describe 'subscription creation' do + context 'when subscription failed' do + before do + allow(hubee_api_client).to receive(:create_subscription).and_raise(Faraday::Error) + end + + it { is_expected.to be_a_success } + + it 'captures an error' do + expect(Sentry).to receive(:set_context).with( + 'DataPass webhook: create FormulaireQF resources', + payload: { authorization_request_id: authorization_request.id } + ) + expect(Sentry).to receive(:capture_exception).with(Faraday::Error) + interactor + end + end + end +end diff --git a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb index 179e697f0..67ed26e67 100644 --- a/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb +++ b/spec/organizers/datapass_webhook/v2/api_particulier_spec.rb @@ -59,10 +59,10 @@ datapass_webhook_params['data']['data']['modalities'] = ['params'] end - it 'does not schedule a job to create formulaire qf access on HubEE' do + it 'does not schedule a job to create formulaire qf resources' do expect { subject - }.not_to have_enqueued_job(CreateFormulaireQFHubEESubscriptionJob) + }.not_to have_enqueued_job(CreateFormulaireQFResourcesJob) end end @@ -76,10 +76,10 @@ datapass_webhook_params['event'] = 'approve' end - it 'schedules a job to create formulaire qf access on HubEE' do + it 'schedules a job to create formulaire qf resources' do expect { subject - }.to have_enqueued_job(CreateFormulaireQFHubEESubscriptionJob) + }.to have_enqueued_job(CreateFormulaireQFResourcesJob) end end @@ -88,10 +88,10 @@ datapass_webhook_params['event'] = 'reject' end - it 'does not schedule a job to create formulaire qf access on HubEE' do + it 'does not schedule a job to create formulaire qf resources' do expect { subject - }.not_to have_enqueued_job(CreateFormulaireQFHubEESubscriptionJob) + }.not_to have_enqueued_job(CreateFormulaireQFResourcesJob) end end end diff --git a/spec/support/insee_sirene_api_mocks.rb b/spec/support/insee_sirene_api_mocks.rb index 2c56643c4..4014cf0c9 100644 --- a/spec/support/insee_sirene_api_mocks.rb +++ b/spec/support/insee_sirene_api_mocks.rb @@ -25,4 +25,8 @@ def insee_sirene_api_not_found_payload } } end + + def read_json_fixture(file) + JSON.parse(Rails.root.join('spec', 'fixtures', file).read) + end end From d0276e2a128377908c5f9076897cbe8d0b2e1286 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Feldis <5403+jbfeldis@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:34:43 +0100 Subject: [PATCH 16/16] Filter out api client files from coverage --- app/clients/formulaire_qf_api_client.rb | 1 + app/clients/hubee_api_authentication.rb | 1 + app/clients/hubee_api_client.rb | 1 + ...create_formulaire_qf_resources_job_spec.rb | 22 +++++++++++++++++++ 4 files changed, 25 insertions(+) create mode 100644 spec/jobs/create_formulaire_qf_resources_job_spec.rb diff --git a/app/clients/formulaire_qf_api_client.rb b/app/clients/formulaire_qf_api_client.rb index a9ac73c1b..45cf86a64 100644 --- a/app/clients/formulaire_qf_api_client.rb +++ b/app/clients/formulaire_qf_api_client.rb @@ -1,3 +1,4 @@ +# :nocov: class FormulaireQFAPIClient def create_collectivity(organization:, editor_id: nil) params = { diff --git a/app/clients/hubee_api_authentication.rb b/app/clients/hubee_api_authentication.rb index 76db47095..e7e0a6819 100644 --- a/app/clients/hubee_api_authentication.rb +++ b/app/clients/hubee_api_authentication.rb @@ -1,3 +1,4 @@ +# :nocov: class HubEEAPIAuthentication < AbstractHubEEAPIClient def access_token http_connection.post( diff --git a/app/clients/hubee_api_client.rb b/app/clients/hubee_api_client.rb index a85c2d044..bb90c4f46 100644 --- a/app/clients/hubee_api_client.rb +++ b/app/clients/hubee_api_client.rb @@ -1,3 +1,4 @@ +# :nocov: class HubEEAPIClient < AbstractHubEEAPIClient # rubocop:disable Metrics/ClassLength class NotFound < StandardError; end class AlreadyExists < StandardError; end diff --git a/spec/jobs/create_formulaire_qf_resources_job_spec.rb b/spec/jobs/create_formulaire_qf_resources_job_spec.rb new file mode 100644 index 000000000..983cbaebd --- /dev/null +++ b/spec/jobs/create_formulaire_qf_resources_job_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +RSpec.describe CreateFormulaireQFResourcesJob do + describe '#perform' do + subject do + described_class.perform_now(authorization_request_id) + end + + let(:authorization_request) { create(:authorization_request, :with_demandeur, :with_contact_technique) } + let(:authorization_request_id) { authorization_request.id } + + before do + allow(DatapassWebhook::CreateFormulaireQFResources).to receive(:call).with(authorization_request:) + end + + it 'creates FormulaireQF resources' do + subject + + expect(DatapassWebhook::CreateFormulaireQFResources).to have_received(:call).with(authorization_request:) + end + end +end