foreman_rh_cloud 12.1.3 → 12.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -5
  3. data/app/controllers/concerns/insights_cloud/package_profile_upload_extensions.rb +33 -0
  4. data/app/controllers/insights_cloud/api/machine_telemetries_controller.rb +1 -2
  5. data/app/controllers/insights_cloud/ui_requests_controller.rb +99 -0
  6. data/app/services/foreman_rh_cloud/cert_auth.rb +9 -1
  7. data/app/services/foreman_rh_cloud/cloud_request_forwarder.rb +12 -13
  8. data/app/services/foreman_rh_cloud/gateway_request.rb +26 -0
  9. data/app/services/foreman_rh_cloud/insights_api_forwarder.rb +116 -0
  10. data/app/services/foreman_rh_cloud/tags_auth.rb +55 -0
  11. data/app/views/api/v2/hosts/insights/base.rabl +6 -0
  12. data/config/routes.rb +2 -0
  13. data/lib/foreman_inventory_upload/async/generate_report_job.rb +11 -5
  14. data/lib/foreman_inventory_upload/async/upload_report_job.rb +15 -4
  15. data/lib/foreman_inventory_upload/generators/archived_report.rb +2 -2
  16. data/lib/foreman_inventory_upload/generators/fact_helpers.rb +65 -13
  17. data/lib/foreman_inventory_upload/generators/queries.rb +7 -5
  18. data/lib/foreman_inventory_upload/generators/slice.rb +0 -1
  19. data/lib/foreman_inventory_upload.rb +2 -2
  20. data/lib/foreman_rh_cloud/engine.rb +5 -3
  21. data/lib/foreman_rh_cloud/version.rb +1 -1
  22. data/lib/insights_cloud.rb +8 -0
  23. data/lib/inventory_sync/async/inventory_hosts_sync.rb +2 -0
  24. data/lib/tasks/rh_cloud_inventory.rake +3 -2
  25. data/package.json +5 -1
  26. data/test/controllers/insights_cloud/ui_requests_controller_test.rb +169 -0
  27. data/test/unit/archived_report_generator_test.rb +1 -1
  28. data/test/unit/fact_helpers_test.rb +267 -2
  29. data/test/unit/services/foreman_rh_cloud/cloud_request_forwarder_test.rb +20 -3
  30. data/test/unit/services/foreman_rh_cloud/insights_api_forwarder_test.rb +176 -0
  31. data/test/unit/services/foreman_rh_cloud/tags_auth_test.rb +29 -0
  32. data/test/unit/slice_generator_test.rb +69 -10
  33. data/webpack/CVEsHostDetailsTab/CVEsHostDetailsTab.js +30 -10
  34. data/webpack/CVEsHostDetailsTab/__tests__/CVEsHostDetailsTab.test.js +18 -11
  35. data/webpack/CVEsHostDetailsTab/index.js +2 -2
  36. data/webpack/ForemanColumnExtensions/index.js +51 -0
  37. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/InventoryFilter.js +1 -0
  38. data/webpack/ForemanInventoryUpload/Components/InventoryFilter/__tests__/__snapshots__/InventoryFilter.test.js.snap +1 -0
  39. data/webpack/ForemanInventoryUpload/Components/InventorySettings/MinimalInventoryDropdown.js +2 -0
  40. data/webpack/ForemanInventoryUpload/Components/PageHeader/PageTitle.js +8 -1
  41. data/webpack/ForemanInventoryUpload/Components/PageHeader/__tests__/__snapshots__/PageTitle.test.js.snap +4 -0
  42. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/CloudConnectorButton.js +3 -3
  43. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudConnectorButton/__tests__/__snapshots__/CloudConnectorButton.test.js.snap +3 -0
  44. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/CloudPingModal/index.js +10 -4
  45. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/PageDescription/PageDescription.js +6 -6
  46. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/SettingsWarning.js +2 -0
  47. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SettingsWarning/__snapshots__/SettingsWarning.test.js.snap +2 -0
  48. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/SyncButton.js +1 -0
  49. data/webpack/ForemanInventoryUpload/Components/PageHeader/components/SyncButton/__tests__/__snapshots__/SyncButton.test.js.snap +1 -0
  50. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/InventoryAutoUpload.js +3 -1
  51. data/webpack/ForemanInventoryUpload/SubscriptionsPageExtension/InventoryAutoUpload/__tests__/__snapshots__/InventoryAutoUpload.test.js.snap +3 -0
  52. data/webpack/ForemanRhCloudFills.js +6 -3
  53. data/webpack/ForemanRhCloudPages.js +6 -3
  54. data/webpack/InsightsCloudSync/Components/InsightsTable/InsightsTable.js +1 -0
  55. data/webpack/InsightsCloudSync/Components/InsightsTable/SelectAllAlert.js +2 -0
  56. data/webpack/InsightsCloudSync/Components/InsightsTable/__tests__/__snapshots__/InsightsTable.test.js.snap +1 -0
  57. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModal.js +3 -0
  58. data/webpack/InsightsCloudSync/Components/RemediationModal/RemediationModalFooter.js +12 -2
  59. data/webpack/InsightsCloudSync/Components/RemediationModal/Resolutions.js +1 -0
  60. data/webpack/InsightsCloudSync/Components/ToolbarDropdown.js +6 -1
  61. data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js +21 -0
  62. data/webpack/InsightsVulnerability/InsightsVulnerabilityListPage.test.js +20 -0
  63. data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +45 -0
  64. data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +28 -0
  65. data/webpack/common/DropdownToggle.js +1 -0
  66. data/webpack/common/ScalprumModule/ScalprumContext.js +63 -0
  67. data/webpack/common/Switcher/SwitcherPF4.js +1 -0
  68. data/webpack/common/Switcher/__tests__/__snapshots__/SwitcherPF4.test.js.snap +1 -0
  69. data/webpack/common/Switcher/index.js +1 -0
  70. data/webpack/global_index.js +3 -0
  71. metadata +19 -4
  72. data/webpack/InsightsVulnerability/InsightsVulnerability.js +0 -13
  73. data/webpack/InsightsVulnerability/InsightsVulnerability.test.js +0 -18
@@ -1,4 +1,5 @@
1
1
  require 'test_plugin_helper'
2
+ require 'digest'
2
3
 
3
4
  class FactHelpersTest < ActiveSupport::TestCase
4
5
  class FactsHelpersTestStub
@@ -29,7 +30,7 @@ class FactHelpersTest < ActiveSupport::TestCase
29
30
 
30
31
  test 'obfuscates ips with insights-client data' do
31
32
  host = mock('host')
32
- @instance.expects(:fact_value).with(host, 'insights_client::ips').returns(
33
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(
33
34
  '[{"obfuscated": "10.230.230.1", "original": "224.0.0.1"}, {"obfuscated": "10.230.230.255", "original": "224.0.0.251"}]'
34
35
  )
35
36
 
@@ -41,11 +42,275 @@ class FactHelpersTest < ActiveSupport::TestCase
41
42
 
42
43
  test 'obfuscates ips without insights-client data' do
43
44
  host = mock('host')
44
- @instance.expects(:fact_value).with(host, 'insights_client::ips').returns(nil)
45
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(nil)
45
46
 
46
47
  actual = @instance.obfuscated_ips(host)
47
48
 
48
49
  assert_equal '10.230.230.1', actual['224.0.0.1']
49
50
  assert_equal '10.230.230.2', actual['224.0.0.2']
50
51
  end
52
+
53
+ describe 'obfuscate_hostname?' do
54
+ test 'returns true when global setting is enabled' do
55
+ Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(true)
56
+ host = mock('host')
57
+
58
+ result = @instance.obfuscate_hostname?(host)
59
+
60
+ assert result
61
+ end
62
+
63
+ test 'returns false when global setting is disabled and no host-specific setting' do
64
+ Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(false)
65
+ host = mock('host')
66
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_hostname_enabled').returns(nil)
67
+
68
+ result = @instance.obfuscate_hostname?(host)
69
+
70
+ refute result
71
+ end
72
+
73
+ test 'returns true when host-specific setting is enabled' do
74
+ Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(false)
75
+ host = mock('host')
76
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_hostname_enabled').returns('true')
77
+
78
+ result = @instance.obfuscate_hostname?(host)
79
+
80
+ assert result
81
+ end
82
+
83
+ test 'returns false when host-specific setting is disabled' do
84
+ Setting.expects(:[]).with(:obfuscate_inventory_hostnames).returns(false)
85
+ host = mock('host')
86
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_hostname_enabled').returns('false')
87
+
88
+ result = @instance.obfuscate_hostname?(host)
89
+
90
+ refute result
91
+ end
92
+ end
93
+
94
+ describe 'fqdn' do
95
+ test 'returns original fqdn when obfuscation is disabled' do
96
+ host = mock('host')
97
+ host.expects(:fqdn).returns('test.example.com')
98
+ @instance.expects(:obfuscate_hostname?).with(host).returns(false)
99
+
100
+ result = @instance.fqdn(host)
101
+
102
+ assert_equal 'test.example.com', result
103
+ end
104
+
105
+ test 'returns obfuscated hostname from insights_client fact when available' do
106
+ host = mock('host')
107
+ host.expects(:fqdn).returns('test.example.com').once
108
+ @instance.expects(:obfuscate_hostname?).with(host).returns(true)
109
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns(
110
+ '[{"original": "test.example.com", "obfuscated": "abc123.example.com"}]'
111
+ )
112
+
113
+ result = @instance.fqdn(host)
114
+
115
+ assert_equal 'abc123.example.com', result
116
+ end
117
+
118
+ test 'returns dynamically obfuscated hostname when insights_client fact is not available' do
119
+ host = mock('host')
120
+ host.stubs(:fqdn).returns('test.example.com')
121
+ @instance.expects(:obfuscate_hostname?).with(host).returns(true)
122
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns(nil)
123
+
124
+ result = @instance.fqdn(host)
125
+
126
+ expected = "#{Digest::SHA1.hexdigest('test.example.com')}.example.com"
127
+ assert_equal expected, result
128
+ end
129
+
130
+ test 'returns dynamically obfuscated hostname when insights_client fact does not contain matching host' do
131
+ host = mock('host')
132
+ host.expects(:fqdn).returns('test.example.com').twice
133
+ @instance.expects(:obfuscate_hostname?).with(host).returns(true)
134
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns(
135
+ '[{"original": "other.example.com", "obfuscated": "abc123.example.com"}]'
136
+ )
137
+ @instance.expects(:obfuscate_fqdn).with('test.example.com').returns('dynamically_obfuscated.example.com')
138
+
139
+ result = @instance.fqdn(host)
140
+
141
+ assert_equal 'dynamically_obfuscated.example.com', result
142
+ end
143
+
144
+ test 'handles invalid JSON in insights_client fact gracefully' do
145
+ host = mock('host')
146
+ host.stubs(:fqdn).returns('test.example.com')
147
+ @instance.expects(:obfuscate_hostname?).with(host).returns(true)
148
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns('invalid json')
149
+
150
+ result = @instance.fqdn(host)
151
+
152
+ expected = "#{Digest::SHA1.hexdigest('test.example.com')}.example.com"
153
+ assert_equal expected, result
154
+ end
155
+
156
+ test 'handles empty insights_client fact' do
157
+ host = mock('host')
158
+ host.stubs(:fqdn).returns('test.example.com')
159
+ @instance.expects(:obfuscate_hostname?).with(host).returns(true)
160
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_hostname').returns('[]')
161
+
162
+ result = @instance.fqdn(host)
163
+
164
+ expected = "#{Digest::SHA1.hexdigest('test.example.com')}.example.com"
165
+ assert_equal expected, result
166
+ end
167
+ end
168
+
169
+ describe 'obfuscate_ips?' do
170
+ test 'returns true when global setting is enabled' do
171
+ Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(true)
172
+ host = mock('host')
173
+
174
+ result = @instance.obfuscate_ips?(host)
175
+
176
+ assert result
177
+ end
178
+
179
+ test 'returns false when global setting is disabled and no host-specific settings' do
180
+ Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
181
+ host = mock('host')
182
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns(nil)
183
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns(nil)
184
+
185
+ result = @instance.obfuscate_ips?(host)
186
+
187
+ refute result
188
+ end
189
+
190
+ test 'returns true when host-specific IPv4 setting is enabled' do
191
+ Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
192
+ host = mock('host')
193
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns('true')
194
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns(nil)
195
+
196
+ result = @instance.obfuscate_ips?(host)
197
+
198
+ assert result
199
+ end
200
+
201
+ test 'returns true when host-specific IPv6 setting is enabled' do
202
+ Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
203
+ host = mock('host')
204
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns(nil)
205
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns('true')
206
+
207
+ result = @instance.obfuscate_ips?(host)
208
+
209
+ assert result
210
+ end
211
+
212
+ test 'returns true when both IPv4 and IPv6 settings are enabled' do
213
+ Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
214
+ host = mock('host')
215
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns('true')
216
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns('true')
217
+
218
+ result = @instance.obfuscate_ips?(host)
219
+
220
+ assert result
221
+ end
222
+
223
+ test 'returns false when both IPv4 and IPv6 settings are disabled' do
224
+ Setting.expects(:[]).with(:obfuscate_inventory_ips).returns(false)
225
+ host = mock('host')
226
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv4_enabled').returns('false')
227
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscate_ipv6_enabled').returns('false')
228
+
229
+ result = @instance.obfuscate_ips?(host)
230
+
231
+ refute result
232
+ end
233
+ end
234
+
235
+ describe 'obfuscate_ip' do
236
+ test 'generates first IP when no existing obfuscated IPs' do
237
+ ips_dict = {}
238
+
239
+ result = @instance.obfuscate_ip('192.168.1.1', ips_dict)
240
+
241
+ assert_equal '10.230.230.1', result
242
+ end
243
+
244
+ test 'generates next sequential IP when existing obfuscated IPs present' do
245
+ ips_dict = { '192.168.1.1' => '10.230.230.5', '192.168.1.2' => '10.230.230.10' }
246
+
247
+ result = @instance.obfuscate_ip('192.168.1.3', ips_dict)
248
+
249
+ assert_equal '10.230.230.11', result
250
+ end
251
+
252
+ test 'handles mixed IP ranges correctly' do
253
+ ips_dict = { '192.168.1.1' => '10.230.230.255', '192.168.1.2' => '10.230.230.1' }
254
+
255
+ result = @instance.obfuscate_ip('192.168.1.3', ips_dict)
256
+
257
+ assert_equal '10.230.231.0', result
258
+ end
259
+
260
+ test 'generates valid IP addresses' do
261
+ ips_dict = {}
262
+
263
+ result = @instance.obfuscate_ip('any.ip.address', ips_dict)
264
+
265
+ assert_match(/\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/, result)
266
+ assert_nothing_raised { IPAddr.new(result) }
267
+ end
268
+ end
269
+
270
+ describe 'obfuscated_ips' do
271
+ test 'handles invalid JSON in insights_client fact gracefully' do
272
+ host = mock('host')
273
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns('invalid json')
274
+
275
+ result = @instance.obfuscated_ips(host)
276
+
277
+ assert_equal '10.230.230.1', result['192.168.1.1']
278
+ end
279
+
280
+ test 'handles empty insights_client fact' do
281
+ host = mock('host')
282
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns('[]')
283
+
284
+ result = @instance.obfuscated_ips(host)
285
+
286
+ assert_equal '10.230.230.1', result['192.168.1.1']
287
+ end
288
+
289
+ test 'preserves existing obfuscated IPs and generates new ones' do
290
+ host = mock('host')
291
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(
292
+ '[{"original": "192.168.1.1", "obfuscated": "10.230.230.5"}]'
293
+ )
294
+
295
+ result = @instance.obfuscated_ips(host)
296
+
297
+ assert_equal '10.230.230.5', result['192.168.1.1']
298
+ assert_equal '10.230.230.6', result['192.168.1.2']
299
+ end
300
+
301
+ test 'default_proc generates unique sequential IPs' do
302
+ host = mock('host')
303
+ @instance.expects(:fact_value).with(host, 'insights_client::obfuscated_ipv4').returns(nil)
304
+
305
+ result = @instance.obfuscated_ips(host)
306
+
307
+ ip1 = result['192.168.1.1']
308
+ ip2 = result['192.168.1.2']
309
+ ip3 = result['192.168.1.3']
310
+
311
+ assert_equal '10.230.230.1', ip1
312
+ assert_equal '10.230.230.2', ip2
313
+ assert_equal '10.230.230.3', ip3
314
+ end
315
+ end
51
316
  end
@@ -3,6 +3,7 @@ require 'puma/null_io'
3
3
 
4
4
  class CloudRequestForwarderTest < ActiveSupport::TestCase
5
5
  include MockCerts
6
+ include KatelloCVEHelper
6
7
 
7
8
  setup do
8
9
  @forwarder = ::ForemanRhCloud::CloudRequestForwarder.new
@@ -10,6 +11,22 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
10
11
  ForemanRhCloud.stubs(:base_url).returns('https://cloud.example.com')
11
12
  ForemanRhCloud.stubs(:cert_base_url).returns('https://cert.cloud.example.com')
12
13
  ForemanRhCloud.stubs(:legacy_insights_url).returns('https://cert-api.access.example.com')
14
+
15
+ UpstreamOnlySettingsTestHelper.set_if_available('allow_multiple_content_views')
16
+ env = FactoryBot.create(:katello_k_t_environment)
17
+ env2 = FactoryBot.create(:katello_k_t_environment, organization: env.organization)
18
+
19
+ @host = FactoryBot.create(
20
+ :host,
21
+ :with_subscription,
22
+ :with_content,
23
+ :with_hostgroup,
24
+ :with_parameter,
25
+ content_view_environments: [make_cve(lifecycle_environment: env), make_cve(lifecycle_environment: env2)],
26
+ organization: env.organization
27
+ )
28
+
29
+ @host.subscription_facet.pools << FactoryBot.create(:katello_pool, account_number: '5678', cp_id: 1)
13
30
  end
14
31
 
15
32
  test 'should prepare correct cloud url' do
@@ -25,7 +42,7 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
25
42
  }
26
43
 
27
44
  paths.each do |key, value|
28
- actual_params = @forwarder.path_params(key, generate_certs_hash)
45
+ actual_params = @forwarder.path_params(key)
29
46
  assert_equal value, actual_params[:url]
30
47
  end
31
48
  end
@@ -150,7 +167,7 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
150
167
  'action_dispatch.request.query_parameters' => params
151
168
  )
152
169
 
153
- actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params, generate_certs_hash)
170
+ actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params, @host)
154
171
 
155
172
  assert_match /foo/, actual[:headers][:user_agent]
156
173
  assert_match /bar/, actual[:headers][:user_agent]
@@ -175,7 +192,7 @@ class CloudRequestForwarderTest < ActiveSupport::TestCase
175
192
  'action_dispatch.request.query_parameters' => params
176
193
  )
177
194
 
178
- actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params, generate_certs_hash)
195
+ actual = @forwarder.prepare_request_opts(req, 'TEST PAYLOAD', params, @host)
179
196
 
180
197
  assert_match /text\/html/, actual[:headers][:content_type]
181
198
  end
@@ -0,0 +1,176 @@
1
+ require 'test_plugin_helper'
2
+ require 'puma/null_io'
3
+
4
+ class UIRequestForwarderTest < ActiveSupport::TestCase
5
+ include MockCerts
6
+
7
+ setup do
8
+ @forwarder = ::ForemanRhCloud::InsightsApiForwarder.new
9
+ @user = FactoryBot.build(:user)
10
+ @organization = FactoryBot.build(:organization)
11
+ @location = FactoryBot.build(:location)
12
+
13
+ setup_certs_expectation do
14
+ @forwarder.stubs(:foreman_certificates)
15
+ end
16
+
17
+ ForemanRhCloud.stubs(:cert_base_url).returns('https://cert.cloud.example.com')
18
+ end
19
+
20
+ test 'should scope GET requests with proper tags' do
21
+ user_agent = { :foo => :bar }
22
+ params = {}
23
+
24
+ req = ActionDispatch::Request.new(
25
+ 'REQUEST_URI' => '/api/vulnerability/v1/cves/abc-123/affected_systems',
26
+ 'REQUEST_METHOD' => 'GET',
27
+ 'HTTP_USER_AGENT' => user_agent,
28
+ 'rack.input' => ::Puma::NullIO.new,
29
+ 'action_dispatch.request.query_parameters' => params
30
+ )
31
+
32
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
33
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
34
+ actual = actual_params[:headers][:params]
35
+ assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tag && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
36
+ true
37
+ end
38
+
39
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves/abc-123/affected_systems', 'test_controller', @user, @organization, @location)
40
+
41
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
42
+ # This is done by setting the expectation before the actual call.
43
+ end
44
+
45
+ test 'should not scope GET requests for unknown uris' do
46
+ user_agent = { :foo => :bar }
47
+ params = {}
48
+
49
+ req = ActionDispatch::Request.new(
50
+ 'REQUEST_URI' => '/api/vulnerability/foo/bar',
51
+ 'REQUEST_METHOD' => 'GET',
52
+ 'HTTP_USER_AGENT' => user_agent,
53
+ 'rack.input' => ::Puma::NullIO.new,
54
+ 'action_dispatch.request.query_parameters' => params
55
+ )
56
+
57
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
58
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
59
+ actual = actual_params[:headers][:params]
60
+ assert_equal 0, actual.count
61
+ true
62
+ end
63
+
64
+ @forwarder.forward_request(req, '/api/vulnerability/foo/bar', 'test_controller', @user, @organization, @location)
65
+
66
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
67
+ # This is done by setting the expectation before the actual call.
68
+ end
69
+
70
+ test 'should merge URI params in GET requests' do
71
+ user_agent = { :foo => :bar }
72
+ params = { :page => 5, :per_page => 42 }
73
+
74
+ req = ActionDispatch::Request.new(
75
+ 'REQUEST_URI' => '/api/vulnerability/v1/cves/abc-123/affected_systems',
76
+ 'REQUEST_METHOD' => 'GET',
77
+ 'HTTP_USER_AGENT' => user_agent,
78
+ 'rack.input' => ::Puma::NullIO.new,
79
+ 'action_dispatch.request.query_parameters' => params
80
+ )
81
+
82
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag)
83
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
84
+ actual = actual_params[:headers][:params]
85
+ assert_equal "U:\"#{@user.login}\"O:\"#{@organization.name}\"L:\"#{@location.name}\"", tag_value(actual.find { |param| param[0] == :tag && tag_name(param[1]) =~ /#{ForemanRhCloud::TagsAuth::TAG_NAME}/ }[1])
86
+ assert_equal 5, actual.find { |param| param[0] == :page }[1]
87
+ assert_equal 42, actual.find { |param| param[0] == :per_page }[1]
88
+ true
89
+ end
90
+
91
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves/abc-123/affected_systems', 'test_controller', @user, @organization, @location)
92
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
93
+ # This is done by setting the expectation before the actual call.
94
+ end
95
+
96
+ test 'should not scope POST requests' do
97
+ post_data = 'Random POST data'
98
+ req = ActionDispatch::Request.new(
99
+ 'REQUEST_URI' => '/foo/bar',
100
+ 'REQUEST_METHOD' => 'POST',
101
+ 'rack.input' => ::Puma::NullIO.new,
102
+ 'RAW_POST_DATA' => post_data
103
+ )
104
+
105
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
106
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
107
+ actual = actual_params[:headers][:params]
108
+ assert_equal 0, actual.count
109
+ true
110
+ end
111
+
112
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
113
+
114
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
115
+ # This is done by setting the expectation before the actual call.
116
+ end
117
+
118
+ test 'should not scope PUT requests' do
119
+ put_data = 'Random PUT data'
120
+ req = ActionDispatch::Request.new(
121
+ 'REQUEST_URI' => '/foo/bar',
122
+ 'REQUEST_METHOD' => 'PUT',
123
+ 'rack.input' => ::Puma::NullIO.new,
124
+ 'RAW_POST_DATA' => put_data
125
+ )
126
+
127
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
128
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
129
+ actual = actual_params[:headers][:params]
130
+ assert_equal 0, actual.count
131
+ true
132
+ end
133
+
134
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
135
+
136
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
137
+ # This is done by setting the expectation before the actual call.
138
+ end
139
+
140
+ test 'should not scope PATCH requests' do
141
+ post_data = 'Random PATCH data'
142
+ req = ActionDispatch::Request.new(
143
+ 'REQUEST_URI' => '/foo/bar',
144
+ 'REQUEST_METHOD' => 'PATCH',
145
+ 'rack.input' => ::Puma::NullIO.new,
146
+ 'RAW_POST_DATA' => post_data,
147
+ "action_dispatch.request.path_parameters" => { :format => "json" }
148
+ )
149
+
150
+ ::ForemanRhCloud::TagsAuth.any_instance.expects(:update_tag).never
151
+ @forwarder.expects(:execute_cloud_request).with do |actual_params|
152
+ actual = actual_params[:headers][:params]
153
+ assert_equal 0, actual.count
154
+ true
155
+ end
156
+
157
+ @forwarder.forward_request(req, '/api/vulnerability/v1/cves', 'test_controller', @user, @organization, @location)
158
+
159
+ # This test asserts the parameters that are sent to the execute_cloud_request method.
160
+ # This is done by setting the expectation before the actual call.
161
+ end
162
+
163
+ def tag_value(param_value)
164
+ return param_value unless param_value.is_a?(String)
165
+
166
+ tag_string = CGI.unescape(param_value)
167
+ tag_string.split('=')[1]
168
+ end
169
+
170
+ def tag_name(param_value)
171
+ return param_value unless param_value.is_a?(String)
172
+
173
+ tag_string = CGI.unescape(param_value)
174
+ tag_string.split('=')[0]
175
+ end
176
+ end
@@ -0,0 +1,29 @@
1
+ require 'test_plugin_helper'
2
+ require 'json'
3
+
4
+ class TagsAuthTest < ActiveSupport::TestCase
5
+ setup do
6
+ @user = FactoryBot.build(:user)
7
+ @logger = Logger.new(IO::NULL)
8
+ @org = FactoryBot.build(:organization)
9
+ @loc = FactoryBot.build(:location)
10
+ @auth = ::ForemanRhCloud::TagsAuth.new(@user, @org, @loc, @logger)
11
+ end
12
+
13
+ test 'Generates tags update request' do
14
+ uuid1 = 'test_uuid1'
15
+ uuid2 = 'test_uuid2'
16
+
17
+ @auth.expects(:allowed_hosts).returns([uuid1, uuid2])
18
+ @auth.expects(:execute_cloud_request).with do |actual_params|
19
+ actual = JSON.parse(actual_params[:payload])
20
+ assert_includes actual['host_id_list'], uuid1
21
+ assert_includes actual['host_id_list'], uuid2
22
+ assert_equal ForemanRhCloud::TagsAuth::TAG_SHORT_NAME, actual['tags'].first['key']
23
+ assert_equal ForemanRhCloud::TagsAuth::TAG_NAMESPACE, actual['tags'].first['namespace']
24
+ assert_equal "U:\"#{@user.login}\"O:\"#{@org.name}\"L:\"#{@loc.name}\"", actual['tags'].first['value']
25
+ end
26
+
27
+ @auth.update_tag
28
+ end
29
+ end
@@ -64,9 +64,10 @@ class SliceGeneratorTest < ActiveSupport::TestCase
64
64
  'dmi::system::product_name',
65
65
  'dmi::chassis::asset_tag',
66
66
  'insights_client::obfuscate_hostname_enabled',
67
+ 'insights_client::obfuscated_hostname',
68
+ 'insights_client::obfuscate_ipv4_enabled',
69
+ 'insights_client::obfuscated_ipv4',
67
70
  'insights_client::hostname',
68
- 'insights_client::obfuscate_ip_enabled',
69
- 'insights_client::ips',
70
71
  'insights_id',
71
72
  ]
72
73
  end
@@ -418,14 +419,38 @@ class SliceGeneratorTest < ActiveSupport::TestCase
418
419
  assert_equal 1, generator.hosts_count
419
420
  end
420
421
 
421
- test 'generates obfuscated ip_address fields with inisghts-client' do
422
+ test 'does not obfuscate fqdn when insights_client obfuscate_hostname_enabled fact is missing and obfuscate_inventory_hostnames setting is false' do
423
+ # Create a host and obfuscated_hostname fact, but do NOT create the obfuscate_hostname_enabled fact
424
+ obfuscated_hostname_data = [
425
+ { 'original' => @host.fqdn, 'obfuscated' => '0dd449d0a027.example.com' },
426
+ ]
427
+ obfuscated_hostname_value = JSON.generate(obfuscated_hostname_data)
428
+ FactoryBot.create(:fact_value,
429
+ fact_name: fact_names['insights_client::obfuscated_hostname'],
430
+ value: obfuscated_hostname_value,
431
+ host: @host)
432
+ # Do NOT create the 'insights_client::obfuscate_hostname_enabled' fact
433
+
434
+ batch = Host.where(id: @host.id).in_batches.first
435
+ generator = create_generator(batch)
436
+
437
+ json_str = generator.render
438
+ actual = JSON.parse(json_str.join("\n"))
439
+
440
+ assert_not_nil(actual_host = actual['hosts'].first)
441
+ assert_equal @host.fqdn, actual_host['fqdn'], "FQDN should not be obfuscated when obfuscate_hostname_enabled is missing and setting is false"
442
+ assert_not_nil(actual_facts = actual_host['facts'].first['facts'])
443
+ assert_not_equal true, actual_facts['is_hostname_obfuscated']
444
+ end
445
+
446
+ test 'generates obfuscated ip_address fields when insights-client facts are present' do
422
447
  nic = FactoryBot.build(:nic_managed)
423
448
  @host.interfaces << nic
424
449
 
425
- FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_ip_enabled'], value: 'true', host: @host)
450
+ FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_ipv4_enabled'], value: 'true', host: @host)
426
451
  FactoryBot.create(
427
452
  :fact_value,
428
- fact_name: fact_names['insights_client::ips'],
453
+ fact_name: fact_names['insights_client::obfuscated_ipv4'],
429
454
  value: "[{\"obfuscated\": \"10.230.230.100\", \"original\": \"#{nic.ip}\"}]",
430
455
  host: @host
431
456
  )
@@ -448,9 +473,17 @@ class SliceGeneratorTest < ActiveSupport::TestCase
448
473
  assert_equal 1, generator.hosts_count
449
474
  end
450
475
 
451
- test 'obfuscates fqdn when instructed by insights-client' do
476
+ test 'obfuscates fqdn when insights-client facts are present' do
477
+ obfuscated_hostname_data = [
478
+ { 'original' => @host.fqdn, 'obfuscated' => '0dd449d0a027.example.com' },
479
+ { 'original' => 'satellite.theforeman.org', 'obfuscated' => 'host2.example.com' },
480
+ ]
481
+ obfuscated_hostname_value = JSON.generate(obfuscated_hostname_data)
482
+ FactoryBot.create(:fact_value,
483
+ fact_name: fact_names['insights_client::obfuscated_hostname'],
484
+ value: obfuscated_hostname_value,
485
+ host: @host)
452
486
  FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_hostname_enabled'], value: 'true', host: @host)
453
- FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::hostname'], value: 'obfuscated_name', host: @host)
454
487
 
455
488
  batch = Host.where(id: @host.id).in_batches.first
456
489
  generator = create_generator(batch)
@@ -460,7 +493,7 @@ class SliceGeneratorTest < ActiveSupport::TestCase
460
493
 
461
494
  assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
462
495
  assert_not_nil(actual_host = actual['hosts'].first)
463
- assert_equal 'obfuscated_name', actual_host['fqdn']
496
+ assert_equal obfuscated_hostname_data.first['obfuscated'], actual_host['fqdn']
464
497
  assert_equal '1234', actual_host['account']
465
498
  assert_not_nil(actual_facts = actual_host['facts'].first['facts'])
466
499
  assert_equal true, actual_facts['is_hostname_obfuscated']
@@ -487,9 +520,35 @@ class SliceGeneratorTest < ActiveSupport::TestCase
487
520
  assert_equal 1, generator.hosts_count
488
521
  end
489
522
 
490
- test 'does not obfuscate fqdn when insights-client sets to false' do
523
+ test 'obfuscates host fqdn with insights-client when setting set' do
524
+ Setting[:obfuscate_inventory_hostnames] = true
525
+ FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::hostname'], value: @host.fqdn, host: @host)
526
+
527
+ batch = Host.where(id: @host.id).in_batches.first
528
+ generator = create_generator(batch)
529
+
530
+ json_str = generator.render
531
+ actual = JSON.parse(json_str.join("\n"))
532
+
533
+ obfuscated_fqdn = Digest::SHA1.hexdigest(@host.fqdn) + '.example.com'
534
+
535
+ assert_equal '00000000-0000-0000-0000-000000000000', actual['report_slice_id']
536
+ assert_not_nil(actual_host = actual['hosts'].first)
537
+ assert_equal obfuscated_fqdn, actual_host['fqdn']
538
+ assert_equal '1234', actual_host['account']
539
+ assert_not_nil(actual_facts = actual_host['facts'].first['facts'])
540
+ assert_equal true, actual_facts['is_hostname_obfuscated']
541
+ assert_equal 1, generator.hosts_count
542
+ end
543
+
544
+ test 'does not obfuscate fqdn when host fact from insights-client has a value of false' do
545
+ obfuscated_hostname_data = [
546
+ { 'original' => @host.fqdn, 'obfuscated' => '0dd449d0a027.example.com' },
547
+ { 'original' => 'satellite.theforeman.org', 'obfuscated' => 'host2.example.com' },
548
+ ]
549
+ obfuscated_hostname_value = JSON.generate(obfuscated_hostname_data)
491
550
  FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscate_hostname_enabled'], value: 'false', host: @host)
492
- FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::hostname'], value: 'obfuscated_name', host: @host)
551
+ FactoryBot.create(:fact_value, fact_name: fact_names['insights_client::obfuscated_hostname'], value: obfuscated_hostname_value, host: @host)
493
552
 
494
553
  batch = Host.where(id: @host.id).in_batches.first
495
554
  generator = create_generator(batch)