Skip to content

Commit

Permalink
Fixes #14158 - Add support for tailoring files
Browse files Browse the repository at this point in the history
  • Loading branch information
Ondrej Prazak committed Dec 15, 2016
1 parent a726ad0 commit a1a6251
Show file tree
Hide file tree
Showing 44 changed files with 835 additions and 126 deletions.
9 changes: 9 additions & 0 deletions .rubocop.yml
Expand Up @@ -21,3 +21,12 @@ Metrics/LineLength:

Style/StringLiterals:
Enabled: false

Style/CollectionMethods:
Enabled: false

Style/DotPosition:
Enabled: false

Style/FrozenStringLiteralComment:
Enabled: false
15 changes: 15 additions & 0 deletions app/assets/javascripts/foreman_openscap/policy_edit.js
Expand Up @@ -13,6 +13,21 @@ function scap_content_selected(element){
})
}

function tailoring_file_selected(element) {
var attrs = attribute_hash(['tailoring_file_id']);
var url = $(element).attr('data-url');
tfm.tools.showSpinner();
$.ajax({
data: attrs,
type: 'post',
url: url,
complete: function() { reloadOnAjaxComplete($(element));},
success: function(request) {
$('#tailoring_file_profile_select').html(request);
}
})
}

function previous_step(previous) {
$('#policy_current_step').val(previous);
$('#new_policy').submit();
Expand Down
16 changes: 14 additions & 2 deletions app/controllers/api/v2/compliance/policies_controller.rb
Expand Up @@ -4,7 +4,7 @@ class PoliciesController < ::Api::V2::BaseController
include Foreman::Controller::SmartProxyAuth
include Foreman::Controller::Parameters::PolicyApi

add_smart_proxy_filters :content, :features => 'Openscap'
add_smart_proxy_filters [:content, :tailoring], :features => 'Openscap'

before_filter :find_resource, :except => %w(index create)

Expand Down Expand Up @@ -46,6 +46,8 @@ def show
param :day_of_month, Integer, :desc => N_('Policy schedule day of month (only if period == "monthly")')
param :cron_line, String, :desc => N_('Policy schedule cron line (only if period == "custom")')
param :hostgroup_ids, Array, :desc => N_('Apply policy to host groups')
param :tailoring_file_id, Integer, :desc => N_('Tailoring file ID')
param :tailoring_file_profile_id, Integer, :desc => N_('Tailoring file profile ID')
param_group :taxonomies, ::Api::V2::BaseController
end
end
Expand Down Expand Up @@ -83,6 +85,16 @@ def content
:filename => @scap_content.original_filename
end

api :GET, '/compliance/policies/:id/tailoring', N_("Show a policy's Tailoring file")
param :id, :identifier, :required => true

def tailoring
@tailoring_file = @policy.tailoring_file
send_data @tailoring_file.scap_file,
:type => 'application/xml',
:filename => @tailoring_file.original_filename
end

private
def find_resource
not_found and return if params[:id].blank?
Expand All @@ -91,7 +103,7 @@ def find_resource

def action_permission
case params[:action]
when 'content'
when 'content', 'tailoring'
:view
else
super
Expand Down
84 changes: 84 additions & 0 deletions app/controllers/api/v2/compliance/tailoring_files_controller.rb
@@ -0,0 +1,84 @@
module Api::V2
module Compliance
class TailoringFilesController < ::Api::V2::BaseController
include Foreman::Controller::Parameters::TailoringFile
before_filter :find_resource, :except => %w(index create)

def resource_name
'::ForemanOpenscap::TailoringFile'
end

def get_resource
instance_variable_get :"@tailoring_file" or fail 'no resource loaded'
end

api :GET, '/compliance/tailoring_files', N_('List Tailoring files')
param_group :search_and_pagination, ::Api::V2::BaseController

def index
@tailoring_files = resource_scope_for_index(:permission => :view_tailoring_files)
end

api :GET, '/compliance/tailoring_files/:id/xml', N_('Show a Tailoring file as XML')
param :id, :identifier, :required => true

def xml
send_data @tailoring_file.scap_file,
:type => 'application/xml',
:filename => @tailoring_file.original_filename
end

api :GET, '/compliance/tailoring_files/:id', N_('Show a Tailoring file')
param :id, :identifier, :required => true
def show
end

def_param_group :tailoring_file do
param :tailoring_file, Hash, :required => true, :action_aware => true do
param :name, String, :required => true, :desc => N_('Tailoring file name')
param :scap_file, String, :required => true, :desc => N_('XML containing tailoring file')
param :original_filename, String, :desc => N_('Original file name of the XML file')
param_group :taxonomies, ::Api::V2::BaseController
end
end

api :POST, '/compliance/tailoring_files', N_('Create a Tailoring file')
param_group :tailoring_file, :as => :create

def create
@tailoring_file = ForemanOpenscap::TailoringFile.new(tailoring_file_params)
process_response @tailoring_file.save
end

api :PUT, '/compliance/tailoring_files/:id', N_('Update a Tailoring file')
param :id, :identifier, :required => true
param_group :tailoring_file

def update
process_response @tailoring_file.update_attributes(tailoring_file_params)
end

api :DELETE, '/compliance/tailoring_files/:id', N_('Deletes a Tailoring file')
param :id, :identifier, :required => true

def destroy
process_response @tailoring_file.destroy
end

private
def find_resource
not_found and return if params[:id].blank?
instance_variable_set("@tailoring_file", resource_scope.find(params[:id]))
end

def action_permission
case params[:action]
when 'xml'
:view
else
super
end
end
end
end
end
Expand Up @@ -4,8 +4,8 @@ module Foreman::Controller::Parameters::PolicyApi
class_methods do
def filter_params_list
[:description, :name, :period, :scap_content_id, :scap_content_profile_id,
:weekday, :day_of_month, :cron_line, :location_ids => [], :organization_ids => [],
:hostgroup_ids => []]
:weekday, :day_of_month, :cron_line, :tailoring_file_id, :tailoring_file_profile_id,
:location_ids => [], :organization_ids => [], :hostgroup_ids => []]
end

def policy_params_filter
Expand Down
@@ -0,0 +1,15 @@
module Foreman::Controller::Parameters::TailoringFile
extend ActiveSupport::Concern

class_methods do
def tailoring_file_params_filter
Foreman::ParameterFilter.new(::ForemanOpenscap::TailoringFile).tap do |filter|
filter.permit :name, :scap_file, :original_filename, :location_ids => [], :organization_ids => []
end
end
end

def tailoring_file_params
self.class.tailoring_file_params_filter.filter_params(params, parameter_filter_context)
end
end
19 changes: 14 additions & 5 deletions app/controllers/policies_controller.rb
Expand Up @@ -4,16 +4,16 @@ class PoliciesController < ApplicationController

before_filter :find_by_id, :only => [:show, :edit, :update, :parse, :destroy]
before_filter :find_multiple, :only => [:select_multiple_hosts, :update_multiple_hosts, :disassociate_multiple_hosts, :remove_policy_from_multiple_hosts]
before_filter :find_tailoring_file, :only => [:tailoring_file_selected]

def model_of_controller
::ForemanOpenscap::Policy
end

def index
@policies = resource_base
.search_for(params[:search], :order => params[:order])
.paginate(:page => params[:page], :per_page => params[:per_page])
.includes(:scap_content, :scap_content_profile)
@policies = resource_base.search_for(params[:search], :order => params[:order])
.paginate(:page => params[:page], :per_page => params[:per_page])
.includes(:scap_content, :scap_content_profile, :tailoring_file)
if @policies.empty? && ForemanOpenscap::ScapContent.unconfigured?
redirect_to scap_contents_path
end
Expand Down Expand Up @@ -70,6 +70,11 @@ def scap_content_selected
end
end

def tailoring_file_selected
@policy ||= ::ForemanOpenscap::Policy.new
render :partial => 'tailoring_file_selected', :locals => { :policy => @policy, :tailoring_file => @tailoring_file }
end

def select_multiple_hosts; end

def update_multiple_hosts
Expand Down Expand Up @@ -104,6 +109,10 @@ def find_by_id
@policy = resource_base.find(params[:id])
end

def find_tailoring_file
@tailoring_file = ForemanOpenscap::TailoringFile.find(params[:tailoring_file_id]) if params[:tailoring_file_id].present?
end

def find_multiple
# Lets search by name or id and make sure one of them exists first
if params[:host_ids].present?
Expand All @@ -126,7 +135,7 @@ def find_multiple

def action_permission
case params[:action]
when 'parse'
when 'parse', 'tailoring_file_selected'
:view
else
super
Expand Down
60 changes: 60 additions & 0 deletions app/controllers/tailoring_files_controller.rb
@@ -0,0 +1,60 @@
class TailoringFilesController < ApplicationController
include Foreman::Controller::AutoCompleteSearch
include Foreman::Controller::Parameters::TailoringFile

before_filter :find_tailoring_file, :only => [:destroy, :update, :edit]
before_filter :handle_file_upload, :only => [:create, :update]

def model_of_controller
::ForemanOpenscap::TailoringFile
end

def index
@tailoring_files = resource_base.search_for(params[:search], :order => params[:order])
.paginate(:page => params[:page], :per_page => params[:per_page])
end

def new
@tailoring_file = ::ForemanOpenscap::TailoringFile.new
end

def create
@tailoring_file = ForemanOpenscap::TailoringFile.new(tailoring_file_params)
if @tailoring_file.save
process_success
else
process_error
end
end

def edit
end

def update
if @tailoring_file.update_attributes(tailoring_file_params)
process_success
else
process_error
end
end

def destroy
if @tailoring_file.destroy
process_success
else
process_error :object => @tailoring_file
end
end

private

def find_tailoring_file
@tailoring_file = resource_base.find(params[:id])
end

def handle_file_upload
return unless params[:tailoring_file] && raw_file = params[:tailoring_file][:scap_file]
params[:tailoring_file][:original_filename] = raw_file.original_filename
params[:tailoring_file][:scap_file] = raw_file.tempfile.read if raw_file.respond_to?(:tempfile) && raw_file.tempfile.respond_to?(:read)
end
end
28 changes: 28 additions & 0 deletions app/helpers/policies_helper.rb
Expand Up @@ -5,6 +5,14 @@ def profiles_selection
return []
end

def policy_profile_from_scap_content(policy)
policy.scap_content_profile.nil? ? "Default" : policy.scap_content_profile.title
end

def effective_policy_profile(policy)
policy.tailoring_file ? policy.tailoring_file_profile.title : policy_profile_from_scap_content(policy)
end

def scap_content_selector(form)
scap_contents = ::ForemanOpenscap::ScapContent.authorized(:view_scap_contents).all
if scap_contents.length > 1
Expand Down Expand Up @@ -38,6 +46,26 @@ def scap_content_profile_selector(form)
end
end

def tailoring_file_selector(form)
select_f form, :tailoring_file_id, ForemanOpenscap::TailoringFile.all.authorized(:view_tailoring_files), :id, :name,
{ :include_blank => _('Choose Tailoring File') },
{ :label => _('Tailoring File'),
:onchange => 'tailoring_file_selected(this)',
:'data-url' => method_path('tailoring_file_selected') }
end

def tailoring_file_profile_selector(form, tailoring_file)
if tailoring_file
select_f form, :tailoring_file_profile_id, tailoring_file.scap_content_profiles, :id, :title,
{ :selected => tailoring_file.scap_content_profiles.first.id },
{ :label => _("XCCDF Profile in Tailoring File"),
:help_inline => _("This profile will be used to override the one from scap content") }
else
select_f form, :tailoring_file_profile_id, [], :id, :title,
{ :include_blank => _('Choose Tailoring File first') }
end
end

def submit_or_cancel_policy(form, overwrite = nil, args = { })
args[:cancel_path] ||= send("#{controller_name}_path")
content_tag(:div, :class => "clearfix") do
Expand Down
8 changes: 6 additions & 2 deletions app/lib/proxy_api/openscap.rb
Expand Up @@ -11,8 +11,12 @@ def fetch_policies_for_scap_content(scap_file)
parse(post(scap_file, "scap_content/policies"))
end

def validate_scap_content(scap_file)
parse(post(scap_file, "scap_content/validator"))
def fetch_profiles_for_tailoring_file(scap_file)
parse(post(scap_file, "tailoring_file/profiles"))
end

def validate_scap_file(scap_file, type)
parse(post(scap_file, "scap_file/validator/#{type}"))
rescue RestClient::RequestTimeout => e
raise ::ProxyAPI::ProxyException.new(url, e, N_("Request timed out. Please try increasing Settings -> proxy_request_timeout"))
end
Expand Down

0 comments on commit a1a6251

Please sign in to comment.