diff --git a/lib/reporting/protocols_report.rb b/lib/reporting/protocols_report.rb index 14c755dbe30..91d7c9e8f0c 100644 --- a/lib/reporting/protocols_report.rb +++ b/lib/reporting/protocols_report.rb @@ -49,6 +49,7 @@ def as_tables overview_table, protocols_table, saml_signature_issues_table, + loa_acr_requests_table, ] end @@ -66,6 +67,10 @@ def as_emailable_reports title: 'SAML Signature Issues', table: saml_signature_issues_table, ), + Reporting::EmailableReport.new( + title: 'LOA ACR Requests', + table: loa_acr_requests_table, + ), ] end @@ -210,6 +215,48 @@ def saml_signature_issues_table ] end + def loa_acr_requests_table + [ + ['Count of integrations using LOA', 'List of issuers with the issue'], + [ + loa_issuers_data.length, + loa_issuers_data.join(', '), + ], + ] + end + + def loa_issuers_data + @loa_issuers_data ||= begin + cloudwatch_client.fetch( + query: loa_issuers_query, + from: time_range.begin, + to: time_range.end, + ). + map { |slice| slice['issuer'] }. + uniq + end + end + + def loa_issuers_query + params = { + event: quote([SAML_AUTH_EVENT, OIDC_AUTH_EVENT]), + } + + format(<<~QUERY, params) + fields + coalesce(properties.event_properties.service_provider, properties.event_properties.client_id) as issuer, + properties.event_properties.acr_values as acr + | parse @message '"authn_context":[*]' as authn + | filter + name IN %{event} + AND (authn like /ns\\/assurance\\/loa/ OR acr like /ns\\/assurance\\/loa/) + AND properties.event_properties.success= 1 + | display issuer + | sort issuer + | dedup issuer + QUERY + end + def to_percent(numerator, denominator) (100.0 * numerator / denominator).round(2) end diff --git a/spec/lib/reporting/protocols_report_spec.rb b/spec/lib/reporting/protocols_report_spec.rb index dcc5ef29ca4..ac70f5e986a 100644 --- a/spec/lib/reporting/protocols_report_spec.rb +++ b/spec/lib/reporting/protocols_report_spec.rb @@ -52,10 +52,22 @@ 'invalid_signature_count' => '2', }, ] + loa_issuers_query_response = [ + { + 'issuer' => 'Issuer1', + }, + { + 'issuer' => 'Issuer2', + }, + { + 'issuer' => 'Issuer3', + }, + ] cloudwatch_client = instance_double('Reporting::CloudwatchClient') allow(cloudwatch_client).to receive(:fetch).and_return( protocol_query_response, saml_signature_query_response, + loa_issuers_query_response, ) allow(report).to receive(:cloudwatch_client).and_return(cloudwatch_client) @@ -81,7 +93,7 @@ describe '#to_csvs' do it 'generates a csv' do csv_string_list = report.to_csvs - expect(csv_string_list.count).to be 3 + expect(csv_string_list.count).to be 4 csvs = csv_string_list.map { |csv| CSV.parse(csv) } @@ -180,6 +192,13 @@ def expected_tables(strings: false) ['Not signing SAML authentication requests', string_or_num(strings, 2), 'Issuer1, Issuer3'], ['Incorrectly signing SAML authentication requests', string_or_num(strings, 1), 'Issuer1'], ], + [ + ['Count of integrations using LOA', 'List of issuers with the issue'], + [ + string_or_num(strings, 3), + 'Issuer1, Issuer2, Issuer3', + ], + ], ] end