foreman_openscap 4.1.0 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/foreman_openscap/policy.css +5 -0
  3. data/app/controllers/api/v2/compliance/oval_contents_controller.rb +72 -0
  4. data/app/controllers/api/v2/compliance/oval_policies_controller.rb +111 -0
  5. data/app/controllers/api/v2/compliance/oval_reports_controller.rb +47 -0
  6. data/app/controllers/api/v2/compliance/scap_contents_controller.rb +2 -0
  7. data/app/controllers/concerns/foreman/controller/parameters/oval_content.rb +22 -0
  8. data/app/controllers/concerns/foreman/controller/parameters/oval_policy.rb +22 -0
  9. data/app/controllers/concerns/foreman_openscap/hosts_controller_extensions.rb +1 -1
  10. data/app/graphql/types/cve.rb +17 -0
  11. data/app/graphql/types/oval_content.rb +17 -0
  12. data/app/graphql/types/oval_policy.rb +21 -0
  13. data/app/helpers/arf_reports_helper.rb +7 -24
  14. data/app/helpers/policies_helper.rb +4 -17
  15. data/app/mailers/foreman_openscap/policy_mailer.rb +2 -2
  16. data/app/models/concerns/foreman_openscap/compliance_status_scoped_search.rb +1 -1
  17. data/app/models/concerns/foreman_openscap/data_stream_content.rb +0 -17
  18. data/app/models/concerns/foreman_openscap/host_extensions.rb +11 -11
  19. data/app/models/concerns/foreman_openscap/hostgroup_extensions.rb +3 -5
  20. data/app/models/concerns/foreman_openscap/inherited_policies.rb +11 -0
  21. data/app/models/concerns/foreman_openscap/oval_facet_host_extensions.rb +38 -0
  22. data/app/models/concerns/foreman_openscap/oval_facet_hostgroup_extensions.rb +15 -0
  23. data/app/models/concerns/foreman_openscap/policy_common.rb +75 -0
  24. data/app/models/concerns/foreman_openscap/scap_file_content.rb +24 -0
  25. data/app/models/foreman_openscap/arf_report.rb +2 -2
  26. data/app/models/foreman_openscap/cve.rb +23 -0
  27. data/app/models/foreman_openscap/host/oval_facet.rb +14 -0
  28. data/app/models/foreman_openscap/host_cve.rb +7 -0
  29. data/app/models/foreman_openscap/hostgroup/oval_facet.rb +14 -0
  30. data/app/models/foreman_openscap/hostgroup_oval_facet_oval_policy.rb +6 -0
  31. data/app/models/foreman_openscap/oval_content.rb +26 -0
  32. data/app/models/foreman_openscap/oval_facet_oval_policy.rb +6 -0
  33. data/app/models/foreman_openscap/oval_policy.rb +54 -0
  34. data/app/models/foreman_openscap/oval_status.rb +45 -0
  35. data/app/models/foreman_openscap/policy.rb +10 -73
  36. data/app/models/foreman_openscap/scap_content.rb +1 -0
  37. data/app/models/foreman_openscap/tailoring_file.rb +1 -0
  38. data/app/services/foreman_openscap/client_config/ansible.rb +39 -6
  39. data/app/services/foreman_openscap/client_config/base.rb +5 -1
  40. data/app/services/foreman_openscap/client_config/puppet.rb +2 -1
  41. data/app/services/foreman_openscap/config_name_service.rb +1 -1
  42. data/app/services/foreman_openscap/hostgroup_overrider.rb +2 -24
  43. data/app/services/foreman_openscap/hostgroup_overrider_common.rb +28 -0
  44. data/app/services/foreman_openscap/lookup_key_overrider.rb +30 -62
  45. data/app/services/foreman_openscap/lookup_key_overrides_common.rb +63 -0
  46. data/app/services/foreman_openscap/oval/check_collection.rb +45 -0
  47. data/app/services/foreman_openscap/oval/configure.rb +80 -0
  48. data/app/services/foreman_openscap/oval/cves.rb +41 -0
  49. data/app/services/foreman_openscap/oval/setup.rb +93 -0
  50. data/app/services/foreman_openscap/oval/setup_check.rb +55 -0
  51. data/app/services/foreman_openscap/oval/sync_oval_contents.rb +42 -0
  52. data/app/views/api/v2/compliance/oval_contents/base.json.rabl +6 -0
  53. data/app/views/api/v2/compliance/oval_contents/create.json.rabl +3 -0
  54. data/app/views/api/v2/compliance/oval_contents/index.json.rabl +3 -0
  55. data/app/views/api/v2/compliance/oval_contents/show.json.rabl +3 -0
  56. data/app/views/api/v2/compliance/oval_contents/sync.json.rabl +3 -0
  57. data/app/views/api/v2/compliance/oval_contents/sync_result.json.rabl +11 -0
  58. data/app/views/api/v2/compliance/oval_contents/update.json.rabl +3 -0
  59. data/app/views/api/v2/compliance/oval_policies/create.json.rabl +3 -0
  60. data/app/views/api/v2/compliance/oval_policies/index.json.rabl +3 -0
  61. data/app/views/api/v2/compliance/oval_policies/main.json.rabl +15 -0
  62. data/app/views/api/v2/compliance/oval_policies/show.json.rabl +3 -0
  63. data/app/views/api/v2/compliance/policies/base.json.rabl +2 -2
  64. data/app/views/api/v2/compliance/policies_common/_attrs.json.rabl +2 -0
  65. data/app/views/arf_reports/_output.html.erb +9 -1
  66. data/app/views/arf_reports/show.html.erb +1 -1
  67. data/app/views/arf_reports/show_html.html.erb +1 -0
  68. data/app/views/compliance_hosts/show.html.erb +1 -8
  69. data/app/views/job_templates/run_oval_scans.erb +24 -0
  70. data/app/views/policies/edit.html.erb +3 -2
  71. data/app/views/policies/show.html.erb +3 -1
  72. data/app/views/policies/steps/_deployment_options_form.html.erb +2 -2
  73. data/app/views/scap_contents/edit.html.erb +2 -12
  74. data/app/views/tailoring_files/edit.html.erb +2 -10
  75. data/config/initializers/inflections.rb +12 -0
  76. data/config/routes.rb +19 -0
  77. data/db/migrate/20201019074925_create_oval_policy.rb +13 -0
  78. data/db/migrate/20201020113801_create_oval_facet.rb +14 -0
  79. data/db/migrate/20201021084109_create_hostgroup_oval_facet.rb +14 -0
  80. data/db/migrate/20201106080924_create_oval_content.rb +12 -0
  81. data/db/migrate/20201116110256_add_oval_content_to_oval_policy.rb +5 -0
  82. data/db/migrate/20201120080329_create_cves.rb +13 -0
  83. data/db/migrate/20201202110213_update_puppet_port_param_type.rb +24 -0
  84. data/db/migrate/20201217130800_add_has_errata_to_cve.rb +8 -0
  85. data/db/migrate/20201217161511_add_url_to_oval_content.rb +5 -0
  86. data/db/migrate/20210409095625_add_oval_policy_reference_to_cve.rb +7 -0
  87. data/db/seeds.d/75-job_templates.rb +3 -2
  88. data/lib/foreman_openscap/bulk_upload.rb +2 -2
  89. data/lib/foreman_openscap/engine.rb +80 -22
  90. data/lib/foreman_openscap/version.rb +1 -1
  91. data/lib/tasks/foreman_openscap_tasks.rake +14 -9
  92. data/locale/de/LC_MESSAGES/foreman_openscap.mo +0 -0
  93. data/locale/de/foreman_openscap.edit.po +0 -0
  94. data/locale/de/foreman_openscap.po +215 -17
  95. data/locale/en_GB/LC_MESSAGES/foreman_openscap.mo +0 -0
  96. data/locale/en_GB/foreman_openscap.edit.po +0 -0
  97. data/locale/en_GB/foreman_openscap.po +213 -15
  98. data/locale/es/LC_MESSAGES/foreman_openscap.mo +0 -0
  99. data/locale/es/foreman_openscap.edit.po +0 -0
  100. data/locale/es/foreman_openscap.po +239 -41
  101. data/locale/foreman_openscap.pot +395 -112
  102. data/locale/fr/LC_MESSAGES/foreman_openscap.mo +0 -0
  103. data/locale/fr/foreman_openscap.edit.po +0 -0
  104. data/locale/fr/foreman_openscap.po +243 -45
  105. data/locale/gl/LC_MESSAGES/foreman_openscap.mo +0 -0
  106. data/locale/gl/foreman_openscap.edit.po +0 -0
  107. data/locale/gl/foreman_openscap.po +213 -15
  108. data/locale/it/LC_MESSAGES/foreman_openscap.mo +0 -0
  109. data/locale/it/foreman_openscap.edit.po +0 -0
  110. data/locale/it/foreman_openscap.po +213 -15
  111. data/locale/ja/LC_MESSAGES/foreman_openscap.mo +0 -0
  112. data/locale/ja/foreman_openscap.edit.po +0 -0
  113. data/locale/ja/foreman_openscap.po +262 -66
  114. data/locale/ko/LC_MESSAGES/foreman_openscap.mo +0 -0
  115. data/locale/ko/foreman_openscap.edit.po +0 -0
  116. data/locale/ko/foreman_openscap.po +214 -16
  117. data/locale/pt_BR/LC_MESSAGES/foreman_openscap.mo +0 -0
  118. data/locale/pt_BR/foreman_openscap.edit.po +0 -0
  119. data/locale/pt_BR/foreman_openscap.po +252 -54
  120. data/locale/ru/LC_MESSAGES/foreman_openscap.mo +0 -0
  121. data/locale/ru/foreman_openscap.edit.po +0 -0
  122. data/locale/ru/foreman_openscap.po +214 -16
  123. data/locale/sv_SE/LC_MESSAGES/foreman_openscap.mo +0 -0
  124. data/locale/sv_SE/foreman_openscap.edit.po +0 -0
  125. data/locale/sv_SE/foreman_openscap.po +213 -15
  126. data/locale/zh_CN/LC_MESSAGES/foreman_openscap.mo +0 -0
  127. data/locale/zh_CN/foreman_openscap.edit.po +0 -0
  128. data/locale/zh_CN/foreman_openscap.po +369 -169
  129. data/locale/zh_TW/LC_MESSAGES/foreman_openscap.mo +0 -0
  130. data/locale/zh_TW/foreman_openscap.edit.po +0 -0
  131. data/locale/zh_TW/foreman_openscap.po +214 -16
  132. data/test/factories/compliance_host_factory.rb +12 -0
  133. data/test/factories/oval_content_factory.rb +7 -0
  134. data/test/factories/oval_policy_factory.rb +9 -0
  135. data/test/files/oval_contents/ansible-2.9.oval.xml.bz2 +0 -0
  136. data/test/fixtures/cve_fixtures.rb +104 -0
  137. data/test/functional/api/v2/compliance/oval_contents_controller_test.rb +39 -0
  138. data/test/functional/api/v2/compliance/oval_policies_controller_test.rb +141 -0
  139. data/test/functional/api/v2/compliance/oval_reports_controller_test.rb +32 -0
  140. data/test/graphql/queries/oval_contents_query_test.rb +35 -0
  141. data/test/graphql/queries/oval_policies_query_test.rb +35 -0
  142. data/test/test_plugin_helper.rb +4 -0
  143. data/test/unit/oval_host_test.rb +45 -0
  144. data/test/unit/oval_policy_test.rb +133 -0
  145. data/test/unit/oval_status_test.rb +47 -0
  146. data/test/unit/services/oval/cves_test.rb +81 -0
  147. data/test/unit/services/oval/setup_test.rb +87 -0
  148. metadata +98 -3
@@ -6,8 +6,8 @@ module ForemanOpenscap
6
6
  @time = options[:time] || 1.day.ago
7
7
 
8
8
  @policies = ::ForemanOpenscap::Policy.all.reject { |policy| policy.assets.map(&:host).compact.empty? }
9
- @compliant_hosts = @policies.map { |policy| Host.comply_with policy }.flatten
10
- @incompliant_hosts = @policies.map { |policy| Host.not_comply_with policy }.flatten
9
+ @compliant_hosts = @policies.map { |policy| ::Host.comply_with policy }.flatten
10
+ @incompliant_hosts = @policies.map { |policy| ::Host.not_comply_with policy }.flatten
11
11
  changed_hosts_of_policies(@policies)
12
12
 
13
13
  if user.nil? || user.mail.nil?
@@ -74,7 +74,7 @@ module ForemanOpenscap
74
74
  end
75
75
 
76
76
  def search_by_host_collection_name(key, operator, value)
77
- scope = apply_condition(Host.joins(:host_collections),
77
+ scope = apply_condition(::Host.joins(:host_collections),
78
78
  operator == '<>',
79
79
  :katello_host_collections => { :name => value })
80
80
  query_conditions_from_scope ForemanOpenscap::ArfReport.where(:host_id => scope)
@@ -1,18 +1,11 @@
1
1
  module ForemanOpenscap
2
2
  module DataStreamContent
3
- require 'digest/sha2'
4
-
5
3
  extend ActiveSupport::Concern
6
4
 
7
5
  included do
8
- validates :digest, :presence => true
9
- validates :scap_file, :presence => true
10
-
11
6
  validates_with ForemanOpenscap::DataStreamValidator
12
7
 
13
8
  after_save :create_profiles, :if => lambda { |ds_content| ds_content.scap_file_previously_changed? }
14
-
15
- before_validation :redigest, :if => lambda { |ds_content| ds_content.persisted? && ds_content.scap_file_changed? }
16
9
  before_destroy ActiveRecord::Base::EnsureNotUsedBy.new(:policies)
17
10
  end
18
11
 
@@ -24,10 +17,6 @@ module ForemanOpenscap
24
17
  @proxy_url
25
18
  end
26
19
 
27
- def digest
28
- self[:digest] ||= Digest::SHA256.hexdigest(scap_file.to_s)
29
- end
30
-
31
20
  def create_profiles
32
21
  fetch_profiles.each do |key, title|
33
22
  create_or_update_profile key, title
@@ -40,11 +29,5 @@ module ForemanOpenscap
40
29
  profile.update(:title => title) unless profile.title == title
41
30
  profile
42
31
  end
43
-
44
- private
45
-
46
- def redigest
47
- self[:digest] = Digest::SHA256.hexdigest(scap_file.to_s)
48
- end
49
32
  end
50
33
  end
@@ -151,13 +151,13 @@ module ForemanOpenscap
151
151
  def search_by_removed_from_policy(key, operator, policy_name)
152
152
  policy = ForemanOpenscap::Policy.find_by :name => policy_name
153
153
  host_ids = policy ? removed_from_policy(policy).pluck(:id) : []
154
- { :conditions => Host::Managed.arel_table[:id].in(host_ids).to_sql }
154
+ { :conditions => ::Host::Managed.arel_table[:id].in(host_ids).to_sql }
155
155
  end
156
156
 
157
157
  def search_by_compliance(key, operator, policy_name, method)
158
158
  policy = ForemanOpenscap::Policy.find_by :name => policy_name
159
159
  host_ids = policy ? public_send(method, policy).pluck(:id) : []
160
- { :conditions => Host::Managed.arel_table[:id].in(host_ids).to_sql }
160
+ { :conditions => ::Host::Managed.arel_table[:id].in(host_ids).to_sql }
161
161
  end
162
162
 
163
163
  def search_by_comply_with(key, operator, policy_name)
@@ -185,12 +185,12 @@ module ForemanOpenscap
185
185
  end
186
186
 
187
187
  def search_by_rule(rule_name, rule_result)
188
- query = Host.joins(:arf_reports)
189
- .merge(ArfReport.latest
190
- .by_rule_result(rule_name, rule_result)
191
- .unscope(:order))
192
- .distinct
193
- .select(Host.arel_table[:id]).to_sql
188
+ query = ::Host.joins(:arf_reports)
189
+ .merge(ArfReport.latest
190
+ .by_rule_result(rule_name, rule_result)
191
+ .unscope(:order))
192
+ .distinct
193
+ .select(::Host.arel_table[:id]).to_sql
194
194
 
195
195
  query_conditions query
196
196
  end
@@ -208,7 +208,7 @@ module ForemanOpenscap
208
208
  else
209
209
  ''
210
210
  end
211
- { :conditions => Host::Managed.arel_table[:id].in(Host::Managed.select(Host::Managed.arel_table[:id]).joins(:policies).where(cond).pluck(:id)).to_sql + host_group_cond }
211
+ { :conditions => ::Host::Managed.arel_table[:id].in(::Host::Managed.select(::Host::Managed.arel_table[:id]).joins(:policies).where(cond).pluck(:id)).to_sql + host_group_cond }
212
212
  end
213
213
 
214
214
  def search_by_policy_id(key, operator, policy_id)
@@ -249,8 +249,8 @@ module ForemanOpenscap
249
249
  .joins(:policies)
250
250
  .where(condition)
251
251
  .pluck(:assetable_id)
252
- subtree_ids = Hostgroup.where(:id => hostgroup_with_policy_ids).flat_map(&:subtree_ids).uniq
253
- Host.where(:hostgroup_id => subtree_ids).where.not(:id => host_ids_from_arf).pluck(:id)
252
+ subtree_ids = ::Hostgroup.where(:id => hostgroup_with_policy_ids).flat_map(&:subtree_ids).uniq
253
+ ::Host.where(:hostgroup_id => subtree_ids).where.not(:id => host_ids_from_arf).pluck(:id)
254
254
  end
255
255
  end
256
256
  end
@@ -2,6 +2,8 @@ module ForemanOpenscap
2
2
  module HostgroupExtensions
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ include InheritedPolicies
6
+
5
7
  included do
6
8
  has_one :asset, :as => :assetable, :class_name => "::ForemanOpenscap::Asset", dependent: :destroy
7
9
  has_many :asset_policies, :through => :asset, :class_name => "::ForemanOpenscap::AssetPolicy"
@@ -9,11 +11,7 @@ module ForemanOpenscap
9
11
  end
10
12
 
11
13
  def inherited_policies
12
- return [] unless parent
13
-
14
- ancestors.inject([]) do |policies, hostgroup|
15
- policies += hostgroup.policies
16
- end.uniq
14
+ find_inherited_policies :policies
17
15
  end
18
16
 
19
17
  def openscap_proxy
@@ -0,0 +1,11 @@
1
+ module ForemanOpenscap
2
+ module InheritedPolicies
3
+ def find_inherited_policies(policy_attr)
4
+ return [] unless parent
5
+
6
+ ancestors.reduce([]) do |policies, hostgroup|
7
+ policies += hostgroup.public_send(policy_attr)
8
+ end.uniq
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,38 @@
1
+ module ForemanOpenscap
2
+ module OvalFacetHostExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ ::Host::Managed::Jail.allow :oval_policies_enc, :oval_policies_enc_raw, :cves, :cves_without_errata
6
+
7
+ included do
8
+ has_many :oval_policies, :through => :oval_facet, :class_name => 'ForemanOpenscap::OvalPolicy'
9
+
10
+ has_many :host_cves, :class_name => 'ForemanOpenscap::HostCve', :foreign_key => :host_id
11
+ has_many :cves, :through => :host_cves, :class_name => 'ForemanOpenscap::Cve', :source => :cve
12
+
13
+ scoped_search :relation => :host_cves, :on => :cve_id, :rename => :cve_id, :complete_value => false
14
+ end
15
+
16
+ def cves_without_errata
17
+ cves.where(:has_errata => false)
18
+ end
19
+
20
+ def cves_with_errata
21
+ cves.where(:has_errata => true)
22
+ end
23
+
24
+ def combined_oval_policies
25
+ combined = oval_policies
26
+ combined += hostgroup.oval_policies + hostgroup.inherited_oval_policies if hostgroup
27
+ combined.uniq
28
+ end
29
+
30
+ def oval_policies_enc_raw
31
+ combined_oval_policies.map(&:to_enc)
32
+ end
33
+
34
+ def oval_policies_enc
35
+ oval_policies_enc_raw.to_json
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ module ForemanOpenscap
2
+ module OvalFacetHostgroupExtensions
3
+ extend ActiveSupport::Concern
4
+
5
+ include InheritedPolicies
6
+
7
+ included do
8
+ has_many :oval_policies, :through => :oval_facet, :class_name => 'ForemanOpenscap::OvalPolicy'
9
+ end
10
+
11
+ def inherited_oval_policies
12
+ find_inherited_policies :oval_policies
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,75 @@
1
+ module ForemanOpenscap
2
+ module PolicyCommon
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_validation :update_period_attrs
7
+ end
8
+
9
+ def cron_line_split
10
+ cron_line.to_s.split(' ')
11
+ end
12
+
13
+ def valid_cron_line
14
+ if period == 'custom'
15
+ errors.add(:cron_line, _("does not consist of 5 parts separated by space")) unless cron_line_split.size == 5
16
+ end
17
+ end
18
+
19
+ def valid_weekday
20
+ if period == 'weekly'
21
+ errors.add(:weekday, _("is not a valid value")) unless Date::DAYNAMES.map(&:downcase).include? weekday
22
+ end
23
+ end
24
+
25
+ def valid_day_of_month
26
+ if period == 'monthly'
27
+ errors.add(:day_of_month, _("must be between 1 and 31")) if !day_of_month || (day_of_month < 1 || day_of_month > 31)
28
+ end
29
+ end
30
+
31
+ def update_period_attrs
32
+ case period
33
+ when 'monthly'
34
+ erase_period_attrs(%w[cron_line weekday])
35
+ when 'weekly'
36
+ erase_period_attrs(%w[cron_line day_of_month])
37
+ when 'custom'
38
+ erase_period_attrs(%w[weekday day_of_month])
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def erase_period_attrs(attrs)
45
+ attrs.each { |attr| self.public_send("#{attr}=", nil) }
46
+ end
47
+
48
+ def period_enc
49
+ # get crontab expression as an array (minute hour day_of_month month day_of_week)
50
+ cron_parts = case period
51
+ when 'weekly'
52
+ ['0', '1', '*', '*', weekday_number.to_s]
53
+ when 'monthly'
54
+ ['0', '1', day_of_month.to_s, '*', '*']
55
+ when 'custom'
56
+ cron_line_split
57
+ else
58
+ raise 'invalid period specification'
59
+ end
60
+
61
+ {
62
+ 'minute' => cron_parts[0],
63
+ 'hour' => cron_parts[1],
64
+ 'monthday' => cron_parts[2],
65
+ 'month' => cron_parts[3],
66
+ 'weekday' => cron_parts[4],
67
+ }
68
+ end
69
+
70
+ def weekday_number
71
+ # 0 is sunday, 1 is monday in cron, while DAYS_INTO_WEEK has 0 as monday, 6 as sunday
72
+ (Date::DAYS_INTO_WEEK.with_indifferent_access[weekday] + 1) % 7
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,24 @@
1
+ module ForemanOpenscap
2
+ module ScapFileContent
3
+ require 'digest/sha2'
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ validates :digest, :presence => true
9
+ validates :scap_file, :presence => true
10
+
11
+ before_validation :redigest, :if => lambda { |file_content| file_content.persisted? && file_content.scap_file_changed? }
12
+ end
13
+
14
+ def digest
15
+ self[:digest] ||= Digest::SHA256.hexdigest(scap_file.to_s)
16
+ end
17
+
18
+ private
19
+
20
+ def redigest
21
+ self[:digest] = Digest::SHA256.hexdigest(scap_file.to_s)
22
+ end
23
+ end
24
+ end
@@ -156,8 +156,8 @@ module ForemanOpenscap
156
156
 
157
157
  def assign_locations_organizations
158
158
  if host
159
- self.location_ids = [host.location_id] if SETTINGS[:locations_enabled]
160
- self.organization_ids = [host.organization_id] if SETTINGS[:organizations_enabled]
159
+ self.location_ids = [host.location_id]
160
+ self.organization_ids = [host.organization_id]
161
161
  end
162
162
  end
163
163
 
@@ -0,0 +1,23 @@
1
+ module ForemanOpenscap
2
+ class Cve < ApplicationRecord
3
+ has_many :host_cves
4
+ has_many :hosts, :through => :host_cves
5
+ has_many :oval_policies, :through => :host_cves
6
+
7
+ scoped_search :relation => :host_cves, :on => :oval_policy_id, :rename => :oval_policy_id, :complete_value => false
8
+
9
+ scope :of_oval_policy, ->(policy_id) {
10
+ joins(:host_cves).where(:foreman_openscap_host_cves => { :oval_policy_id => policy_id })
11
+ }
12
+
13
+ scope :of_host, ->(host_id) {
14
+ joins(:host_cves).where(:foreman_openscap_host_cves => { :host_id => host_id })
15
+ }
16
+
17
+ validates :ref_id, :ref_url, :definition_id, :presence => true
18
+
19
+ class Jail < ::Safemode::Jail
20
+ allow :ref_id, :ref_url
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ module ForemanOpenscap
2
+ module Host
3
+ class OvalFacet < ApplicationRecord
4
+ self.table_name = 'foreman_openscap_oval_facets'
5
+
6
+ include Facets::Base
7
+
8
+ validates :host, :presence => true, :allow_blank => false
9
+
10
+ has_many :oval_facet_oval_policies, :dependent => :destroy, :class_name => 'ForemanOpenscap::OvalFacetOvalPolicy'
11
+ has_many :oval_policies, :through => :oval_facet_oval_policies, :class_name => 'ForemanOpenscap::OvalPolicy'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ module ForemanOpenscap
2
+ class HostCve < ApplicationRecord
3
+ belongs_to_host
4
+ belongs_to :cve
5
+ belongs_to :oval_policy
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ module ForemanOpenscap
2
+ module Hostgroup
3
+ class OvalFacet < ApplicationRecord
4
+ self.table_name = 'foreman_openscap_hostgroup_oval_facets'
5
+
6
+ include Facets::HostgroupFacet
7
+
8
+ validates :hostgroup, :presence => true, :allow_blank => false
9
+
10
+ has_many :hostgroup_oval_facet_oval_policies, :dependent => :destroy, :class_name => 'ForemanOpenscap::HostgroupOvalFacetOvalPolicy'
11
+ has_many :oval_policies, :through => :hostgroup_oval_facet_oval_policies, :class_name => 'ForemanOpenscap::OvalPolicy'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ module ForemanOpenscap
2
+ class HostgroupOvalFacetOvalPolicy < ApplicationRecord
3
+ belongs_to :oval_policy
4
+ belongs_to :oval_facet, :class_name => 'ForemanOpenscap::Hostgroup::OvalFacet'
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ module ForemanOpenscap
2
+ class OvalContent < ApplicationRecord
3
+ audited :except => [:scap_file]
4
+ include Authorizable
5
+ include Taxonomix
6
+ include ScapFileContent
7
+
8
+ scoped_search :on => :name, :complete_value => true
9
+
10
+ has_many :oval_policies
11
+ validates :name, :presence => true, :length => { :maximum => 255 }, uniqueness: true
12
+ validates :url, :format => { :with => %r{\Ahttps?://} }, :allow_blank => true
13
+
14
+ before_validation :fetch_remote_content, :if => lambda { |oval_content| oval_content.url.present? }
15
+
16
+ def to_h
17
+ { :id => id, :name => name, :original_filename => original_filename, :changed_at => changed_at }
18
+ end
19
+
20
+ private
21
+
22
+ def fetch_remote_content
23
+ ForemanOpenscap::Oval::SyncOvalContents.new.sync self
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ module ForemanOpenscap
2
+ class OvalFacetOvalPolicy < ApplicationRecord
3
+ belongs_to :oval_policy
4
+ belongs_to :oval_facet, :class_name => 'ForemanOpenscap::Host::OvalFacet'
5
+ end
6
+ end
@@ -0,0 +1,54 @@
1
+ module ForemanOpenscap
2
+ class OvalPolicy < ApplicationRecord
3
+ graphql_type '::Types::OvalPolicy'
4
+
5
+ audited
6
+ include Authorizable
7
+ include Taxonomix
8
+
9
+ include PolicyCommon
10
+
11
+ belongs_to :oval_content
12
+
13
+ validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 255 }
14
+ validates :period, :inclusion => { :in => %w[weekly monthly custom], :message => _('is not a valid value') }
15
+ validate :valid_cron_line, :valid_weekday, :valid_day_of_month
16
+ validates :oval_content, :presence => true
17
+
18
+ has_many :oval_facet_oval_policies, :class_name => 'ForemanOpenscap::OvalFacetOvalPolicy'
19
+ has_many :oval_facets, :through => :oval_facet_oval_policies, :class_name => 'ForemanOpenscap::Host::OvalFacet'
20
+ has_many :hosts, :through => :oval_facets
21
+
22
+ has_many :hostgroup_oval_facet_oval_policies, :class_name => 'ForemanOpenscap::HostgroupOvalFacetOvalPolicy'
23
+ has_many :hostgroup_oval_facets, :through => :hostgroup_oval_facet_oval_policies, :class_name => 'ForemanOpenscap::Hostgroup::OvalFacet', :source => :oval_facet
24
+ has_many :hostgroups, :through => :hostgroup_oval_facets
25
+
26
+ has_many :host_cves
27
+ has_many :cves, :through => :host_cves
28
+
29
+ def host_ids=(host_ids)
30
+ self.oval_facets = facets_to_assign(host_ids, :host_id, ForemanOpenscap::Host::OvalFacet)
31
+ end
32
+
33
+ def hostgroup_ids=(hostgroup_ids)
34
+ self.hostgroup_oval_facets = facets_to_assign(hostgroup_ids, :hostgroup_id, ForemanOpenscap::Hostgroup::OvalFacet)
35
+ end
36
+
37
+ def to_enc
38
+ {
39
+ :id => id,
40
+ :oval_content_path => "/var/lib/openscap/oval_content/#{oval_content.digest}.oval.xml.bz2",
41
+ :download_path => "/compliance/oval_policies/#{id}/oval_content/#{oval_content.digest}"
42
+ }.merge(period_enc).with_indifferent_access
43
+ end
44
+
45
+ private
46
+
47
+ def facets_to_assign(ids, key, facet_class)
48
+ filtered_ids = ids.uniq.reject { |id| respond_to?(:empty) && id.empty? }
49
+ existing_facets = facet_class.where(key => filtered_ids)
50
+ new_facets = (filtered_ids - existing_facets.pluck(key)).map { |id| facet_class.new(key => id) }
51
+ existing_facets + new_facets
52
+ end
53
+ end
54
+ end