Skip to content
This repository has been archived by the owner on Jul 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #18 from aaronlippold/control_filter
Browse files Browse the repository at this point in the history
Added filtering capability, forms, and tests
  • Loading branch information
robthew authored May 24, 2018
2 parents b22944b + 0d20932 commit 763a157
Show file tree
Hide file tree
Showing 59 changed files with 2,157 additions and 425 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ gem 'thor'
gem 'json'
gem 'pry'

gem 'inspec_to', :git => "git@gitlab.mitre.org:inspec/inspec_to.git"

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
Expand Down
15 changes: 15 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@
padding: 5px;
font-size: 70px;
}
.padded-right {
padding-right: 35px;
}
.no-top-padding {
padding-top: 0px;
padding-bottom: 5px;
}
.little_wider {
min-width: 200px;
}
.span-title {
font-size: 18px;
margin: 0;
line-height: 1;
}
.column-2 {
-webkit-columns: 100px 2; /* Chrome, Safari, Opera */
-moz-columns: 100px 2; /* Firefox */
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/concerns/dashboard_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class DashboardController < ApplicationController
def index
# nop
session[:filter] = nil
end
end
68 changes: 58 additions & 10 deletions app/controllers/evaluations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class EvaluationsController < ApplicationController
load_resource
authorize_resource only: [:show, :destroy, :filter]
authorize_resource only: [:show, :destroy, :filter, :clear_filter]
protect_from_forgery

# GET /evaluations
Expand All @@ -12,10 +12,10 @@ def index
# GET /evaluations/1
# GET /evaluations/1.json
def show
logger.debug "params: #{params.inspect}"
@profiles = @evaluation.profiles
@counts, @controls = @evaluation.status_counts
@nist_hash = ProfilesController.nist_800_53
filters, @filter_label = session_filters
@counts, @controls = @evaluation.status_counts(filters)
@nist_hash = Constants::NIST_800_53
respond_to do |format|
format.html { render :show }
format.json { render :show }
Expand All @@ -37,9 +37,8 @@ def destroy
# GET /profiles/1.json
def ssp
authorize! :read, Evaluation
@nist_hash = ProfilesController.nist_800_53
@nist_hash = Constants::NIST_800_53
@symbols = @evaluation.symbols
# @counts, @controls = @evaluation.status_counts
@evaluation.profiles.each do |profile|
families, nist = profile.control_families
next if families.empty?
Expand All @@ -61,14 +60,46 @@ def ssp

def nist
authorize! :read, Evaluation
filters, = session_filters
category = nil
category = params[:category].downcase if params.key?(:category)
status_sym = nil
status_sym = params[:status_symbol].downcase.tr(' ', '_').to_sym if params.key?(:status_symbol)
@control_hash = @evaluation.nist_hash category, status_sym
nist_hash = ProfilesController.nist_800_53
@name = nist_hash['name']
@families = nist_hash['children']
@control_hash = @evaluation.nist_hash category, status_sym, filters
@name = Constants::NIST_800_53['name']
@families = Constants::NIST_800_53['children']
end

def clear_filter
session[:filter] = nil
session[:filter_group] = nil
redirect_to @evaluation
end

def filter
logger.debug "params: #{params.inspect}"
f_params = params[:filter]
@filter = Filter.valid_filter f_params
if f_params[:save_filter]
@filter.save
end
session[:filter] = @filter
session[:filter_group] = nil
redirect_to @evaluation
end

def filter_select
filter_params = params[:filter_group]
if filter_params[:id].present?
@filter_group = FilterGroup.find(filter_params[:id])
session[:filter] = nil
session[:filter_group] = @filter_group
elsif filter_params[:filter_ids].present?
@filter = Filter.find(filter_params[:filter_ids])
session[:filter_group] = nil
session[:filter] = @filter
end
redirect_to @evaluation
end

def upload
Expand All @@ -81,4 +112,21 @@ def upload
redirect_to evaluations_url, notice: 'File does not contain an evaluation.'
end
end

private

def session_filters
filters = nil
filter_label = nil
if session[:filter]
filter = session[:filter].is_a?(Filter) ? session[:filter] : Filter.new(session[:filter])
filters = [filter]
filter_label = filter.to_s
elsif session[:filter_group]
filter_group = session[:filter_group].is_a?(FilterGroup) ? session[:filter_group] : FilterGroup.new(session[:filter_group])
filters = filter_group.filters
filter_label = "#{filter_group.name}: #{filter_group.filters.map(&:to_s).join(', ')}"
end
[filters, filter_label]
end
end
81 changes: 81 additions & 0 deletions app/controllers/filter_groups_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
class FilterGroupsController < ApplicationController
load_and_authorize_resource
protect_from_forgery
# authorize_resource only: [:show, :destroy, :filter, :clear_filter]
# before_action :set_filter_group, only: [:show, :edit, :update, :destroy, :remove_filter]

# GET /filter_groups
# GET /filter_groups.json
def index
@filter_groups = FilterGroup.all
end

# GET /filter_groups/1
# GET /filter_groups/1.json
def show
end

# GET /filter_groups/new
def new
@filter_group = FilterGroup.new
end

# GET /filter_groups/1/edit
def edit
end

# POST /filter_groups
# POST /filter_groups.json
def create
@filter_group = FilterGroup.new(filter_group_params)

respond_to do |format|
if @filter_group.save
format.html { redirect_to @filter_group, notice: 'Filter group was successfully created.' }
format.json { render :show, status: :created, location: @filter_group }
else
format.html { render :new }
format.json { render json: @filter_group.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /filter_groups/1
# PATCH/PUT /filter_groups/1.json
def update
logger.debug "filter_group_params: #{filter_group_params.inspect}"
if (filter_ids = filter_group_params[:filter_ids])
if (filter = Filter.find(filter_ids[:id]))
@filter_group.filters << filter
redirect_to @filter_group, notice: 'Filter was added.'
end
else
respond_to do |format|
if @filter_group.update(filter_group_params)
format.html { redirect_to @filter_group, notice: 'Filter group was successfully updated.' }
format.json { render :show, status: :ok, location: @filter_group }
else
format.html { render :edit }
format.json { render json: @filter_group.errors, status: :unprocessable_entity }
end
end
end
end

# DELETE /filter_groups/1
# DELETE /filter_groups/1.json
def destroy
@filter_group.destroy
respond_to do |format|
format.html { redirect_to filter_groups_url, notice: 'Filter group was successfully destroyed.' }
format.json { head :no_content }
end
end

private

# Never trust parameters from the scary internet, only allow the white list through.
def filter_group_params
params.require(:filter_group).permit(:name, { filter_ids: [:id] })
end
end
73 changes: 73 additions & 0 deletions app/controllers/filters_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
class FiltersController < ApplicationController
load_and_authorize_resource
protect_from_forgery

# GET /filters
# GET /filters.json
def index
@filters = Filter.all
end

# GET /filters/1
# GET /filters/1.json
def show
end

# GET /filters/new
def new
@filter = Filter.new
@nist_hash = Constants::NIST_800_53
end

# GET /filters/1/edit
def edit
@nist_hash = Constants::NIST_800_53
end

# POST /filters
# POST /filters.json
def create
@filter = Filter.valid_filter filter_params
@filter.save
respond_to do |format|
format.html { redirect_to Filter.find(@filter.id), notice: 'Filter was successfully created.' }
format.json { render :show, status: :created, location: @filter }
end
end

# PATCH/PUT /filters/1
# PATCH/PUT /filters/1.json
def update
respond_to do |format|
@filter.update(filter_params)
format.html { redirect_to @filter, notice: 'Filter was successfully updated.' }
format.json { render :show, status: :ok, location: @filter }
end
end

# DELETE /filters/1
# DELETE /filters/1.json
def destroy
if params.key?(:filter_group_id)
@filter_group = FilterGroup.find(params[:filter_group_id])
@filter_group.filters.delete(Filter.find(params[:id]))
respond_to do |format|
format.html { redirect_to @filter_group, notice: 'Filter was successfully removed.' }
format.json { head :no_content }
end
else
@filter.destroy
respond_to do |format|
format.html { redirect_to filters_url, notice: 'Filter was successfully destroyed.' }
format.json { head :no_content }
end
end
end

private

# Never trust parameters from the scary internet, only allow the white list through.
def filter_params
params.require(:filter).permit(family: [], number: [], sub_fam: [], sub_num: [], enhancement: [], enh_sub_fam: [], enh_sub_num: [])
end
end
16 changes: 1 addition & 15 deletions app/controllers/profiles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ class ProfilesController < ApplicationController
load_resource
authorize_resource only: [:show, :edit, :destroy, :upload]

@nist_800_53_json = nil

class << self
attr_accessor :nist_800_53_json
end

# GET /profiles
# GET /profiles.json
def index
Expand Down Expand Up @@ -71,7 +65,7 @@ def nist
category = nil
category = params[:category].downcase if params.key?(:category)
@control_hash = @profile.nist_hash category
nist_hash = ProfilesController.nist_800_53
nist_hash = Constants::NIST_800_53
@name = nist_hash['name']
@families = nist_hash['children']
end
Expand All @@ -96,14 +90,6 @@ def upload
end
end

def self.nist_800_53
unless ProfilesController.nist_800_53_json
file = File.read("#{Rails.root}/data/nist_800_53.json")
ProfilesController.nist_800_53_json = JSON.parse(file)
end
ProfilesController.nist_800_53_json
end

private

# Never trust parameters from the scary internet, only allow the white list through.
Expand Down
5 changes: 5 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,9 @@ def result_message(symbol)
'No test available for this control'
end
end

def ary_to_s(val)
return '' if val.nil? || val.empty?
val.size == 1 ? val.first.to_s.delete('"') : val.to_s.delete('"')
end
end
2 changes: 2 additions & 0 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def initialize(user)
Role,
Support,
Tag,
Filter,
FilterGroup,
], created_by_id: user.id
end
if user.has_role?(:admin)
Expand Down
25 changes: 25 additions & 0 deletions app/models/control.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,31 @@ def severity
end
end

def parse_nist_tag(nist_tag)
if (m_fields = nist_tag.match(/([A-Z]{2})\-(\d+)((\s*([a-z])|\.([a-z])){1}((\.|\s+)(\d+))?)?\s*(\(\d+\))?((\s*([a-z])|\.([a-z])|\s*\(([a-z])\)){1}((\.|\s+)(\d+))?)?/))
# <MatchData "AC-15 a 3(2) b 2" 1:"AC" 2:"15" 3:" a 3" 4:" a" 5:"a" 6:nil 7:" 3" 8:" " 9:"3" 10:"(2)" 11:" b 2" 12:" b" 13:"b" 14:nil 15:nil 16:" 2" 17:" " 18:"2">
value = "#{m_fields[1]}-#{m_fields[2]}"
value += ".#{m_fields[5] || m_fields[6]}" if m_fields[4].present?
value += ".#{m_fields[9]}" if m_fields[9].present?
value += m_fields[10] if m_fields[10].present?
value += ".#{m_fields[13] || m_fields[14] || m_fields[15]}" if m_fields[12].present?
value += ".#{m_fields[18]}" if m_fields[18].present?
value
else
nist_tag
end
end

def nist_tags
values = []
if (nist_tags = tag('nist'))
nist_tags.split(',').map(&:strip).each do |nist_tag|
values << parse_nist_tag(nist_tag)
end
end
values
end

def short_title
title.nil? ? '' : "#{title[0..50]}..."
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/download.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def to_pdf
'margin-bottom': '0.10in',
'margin-left': '0.10in'
}
kit = PDFKit.new(as_html, options=options)
kit = PDFKit.new(as_html, options)
kit.to_file('tmp/ssp.pdf')
end

Expand Down
Loading

0 comments on commit 763a157

Please sign in to comment.