diff --git a/site/app/clients/abstract_data_pass_api_client.rb b/site/app/clients/abstract_data_pass_api_client.rb new file mode 100644 index 0000000000..ec880426e9 --- /dev/null +++ b/site/app/clients/abstract_data_pass_api_client.rb @@ -0,0 +1,23 @@ +require 'faraday' + +class AbstractDataPassAPIClient + protected + + def http_connection(&block) + 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 client_id + AdminApientreprise.credentials[:datapass_client_id] + end + + def client_secret + AdminApientreprise.credentials[:datapass_client_secret] + end +end diff --git a/site/app/clients/data_pass_api_authentication.rb b/site/app/clients/data_pass_api_authentication.rb new file mode 100644 index 0000000000..b390cddc80 --- /dev/null +++ b/site/app/clients/data_pass_api_authentication.rb @@ -0,0 +1,21 @@ +# :nocov: +class DataPassAPIAuthentication < AbstractDataPassAPIClient + def access_token + http_connection.post( + auth_url, + URI.encode_www_form( + grant_type: 'client_credentials', + client_id:, + client_secret:, + scope: 'read_authorizations' + ), + 'Content-Type' => 'application/x-www-form-urlencoded' + ).body['access_token'] + end + + private + + def auth_url + "#{DataPass::BASE_URL}/api/oauth/token" + end +end diff --git a/site/app/clients/data_pass_api_client.rb b/site/app/clients/data_pass_api_client.rb new file mode 100644 index 0000000000..995b12f5d4 --- /dev/null +++ b/site/app/clients/data_pass_api_client.rb @@ -0,0 +1,14 @@ +# :nocov: +class DataPassAPIClient < AbstractDataPassAPIClient + def definitions(api) + http_connection.get("#{DataPass::BASE_URL}/api/v1/definitions/#{api}").body + end + + protected + + def http_connection + super do |conn| + conn.request :authorization, 'Bearer', -> { DataPassAPIAuthentication.new.access_token } + end + end +end diff --git a/site/app/helpers/scope_helper.rb b/site/app/helpers/scope_helper.rb index f188d67b03..1db5b9ec4d 100644 --- a/site/app/helpers/scope_helper.rb +++ b/site/app/helpers/scope_helper.rb @@ -1,4 +1,6 @@ module ScopeHelper + UNKNOWN_SCOPE_GROUP = 'Autres'.freeze + def build_scopes(scopes, api) scopes_tree = {} scopes.each do |scope| @@ -9,11 +11,23 @@ def build_scopes(scopes, api) end def humanize_scope(scope, api) - I18n.t("api_#{api}.tokens.token.scope.#{scope}.label", default: scope.humanize) + entry = ScopeCatalog.for(api).lookup(scope) + scope_display_parts(api, entry, scope).join(' || ') end private + def scope_display_parts(api, entry, scope) + name = entry&.dig(:name).presence || scope.humanize + provider = entry&.dig(:provider).presence || UNKNOWN_SCOPE_GROUP + if api == 'api_particulier' + group = entry&.dig(:group).presence || UNKNOWN_SCOPE_GROUP + [provider, group, name] + else + [provider, name] + end + end + def build_scopes_parts(scopes_tree, splitted_scope) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity if splitted_scope.size > 2 scopes_tree[splitted_scope[0]] ||= {} diff --git a/site/app/mailers/api_entreprise/authorization_request_mailer.rb b/site/app/mailers/api_entreprise/authorization_request_mailer.rb index 1f2feef919..c30801711a 100644 --- a/site/app/mailers/api_entreprise/authorization_request_mailer.rb +++ b/site/app/mailers/api_entreprise/authorization_request_mailer.rb @@ -3,6 +3,8 @@ class APIEntreprise::AuthorizationRequestMailer < APIEntrepriseMailer include ExternalUrlHelper + helper :scope + %w[ embarquement_demande_refusee update_embarquement_demande_refusee @@ -20,9 +22,8 @@ class APIEntreprise::AuthorizationRequestMailer < APIEntrepriseMailer update_demande_recue ].each do |method| send('define_method', method) do |args| - @all_scopes = I18n.t('api_entreprise.tokens.token.scope') @authorization_request = args[:authorization_request] - @authorization_request_scopes = @authorization_request.scopes.map(&:to_sym).presence + @authorization_request_scopes = @authorization_request.scopes.presence @authorization_request_datapass_url = datapass_authorization_request_url(@authorization_request) @full_name_demandeur = @authorization_request.demandeur.full_name diff --git a/site/app/mailers/api_particulier/authorization_request_mailer.rb b/site/app/mailers/api_particulier/authorization_request_mailer.rb index ecca637505..bf7f8b1282 100644 --- a/site/app/mailers/api_particulier/authorization_request_mailer.rb +++ b/site/app/mailers/api_particulier/authorization_request_mailer.rb @@ -1,6 +1,8 @@ class APIParticulier::AuthorizationRequestMailer < APIParticulierMailer include ExternalUrlHelper + helper :scope + %w[ demande_recue update_demande_recue @@ -16,9 +18,8 @@ class APIParticulier::AuthorizationRequestMailer < APIParticulierMailer update_embarquement_valide_to_demandeur ].each do |method| send('define_method', method) do |args| - @all_scopes = I18n.t('api_particulier.tokens.token.scope') @authorization_request = args[:authorization_request] - @authorization_request_scopes = @authorization_request.scopes.map(&:to_sym).presence + @authorization_request_scopes = @authorization_request.scopes.presence @authorization_request_datapass_url = datapass_authorization_request_url(@authorization_request) @full_name_demandeur = @authorization_request.demandeur.full_name diff --git a/site/app/services/scope_catalog.rb b/site/app/services/scope_catalog.rb new file mode 100644 index 0000000000..8d7d91740a --- /dev/null +++ b/site/app/services/scope_catalog.rb @@ -0,0 +1,42 @@ +class ScopeCatalog + CACHE_TTL = ENV.fetch('DATAPASS_SCOPE_CATALOG_CACHE_TTL_MINUTES', '360').to_i.minutes + + def self.for(api) + new(api) + end + + def initialize(api) + @api = api + end + + def lookup(scope_value) + scopes[scope_value] + end + + private + + attr_reader :api + + def scopes + Rails.cache.fetch(cache_key, expires_in: CACHE_TTL) do + fetch_scopes.tap { |data| Rails.cache.write(stale_cache_key, data, expires_in: nil) } + end + rescue Faraday::Error, TypeError, NoMethodError => e + Sentry.capture_exception(e) + Rails.cache.read(stale_cache_key) || {} + end + + def fetch_scopes + DataPassAPIClient.new.definitions(api)['scopes'].to_h do |scope| + [scope['value'], { provider: scope['provider'], group: scope['group'], name: scope['name'] }] + end + end + + def cache_key + "data_pass_scope_catalog/#{api}" + end + + def stale_cache_key + "#{cache_key}/stale" + end +end diff --git a/site/app/views/api_entreprise/authorization_request_mailer/_list_scopes.html.mjml b/site/app/views/api_entreprise/authorization_request_mailer/_list_scopes.html.mjml index f8360a9695..4f13d0a923 100644 --- a/site/app/views/api_entreprise/authorization_request_mailer/_list_scopes.html.mjml +++ b/site/app/views/api_entreprise/authorization_request_mailer/_list_scopes.html.mjml @@ -4,12 +4,10 @@ 🔐 Cette habilitation donne accĂšs aux API suivantes : diff --git a/site/app/views/api_particulier/authorization_request_mailer/_list_scopes.html.mjml b/site/app/views/api_particulier/authorization_request_mailer/_list_scopes.html.mjml index 2e3a3dc648..f43da9a576 100644 --- a/site/app/views/api_particulier/authorization_request_mailer/_list_scopes.html.mjml +++ b/site/app/views/api_particulier/authorization_request_mailer/_list_scopes.html.mjml @@ -3,12 +3,10 @@ 🔐 Cette habilitation donne accĂšs aux API suivantes : diff --git a/site/app/views/api_particulier/endpoints/show.html.erb b/site/app/views/api_particulier/endpoints/show.html.erb index eb680f2826..ee32c20085 100644 --- a/site/app/views/api_particulier/endpoints/show.html.erb +++ b/site/app/views/api_particulier/endpoints/show.html.erb @@ -232,7 +232,7 @@