opencontrol-linter 0.1

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 (32) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +94 -0
  4. data/exe/opencontrol-linter +8 -0
  5. data/lib/opencontrol.rb +3 -0
  6. data/lib/opencontrol/cli.rb +231 -0
  7. data/lib/opencontrol/messages.rb +45 -0
  8. data/lib/opencontrol/version.rb +22 -0
  9. data/vendor/README.md +9 -0
  10. data/vendor/schemas/CONTRIBUTING.md +37 -0
  11. data/vendor/schemas/README.md +175 -0
  12. data/vendor/schemas/examples/component_v3.0.0.yaml +70 -0
  13. data/vendor/schemas/examples/component_v3.1.0.yaml +81 -0
  14. data/vendor/schemas/examples/opencontrol_v1.0.0.yaml +22 -0
  15. data/vendor/schemas/kwalify/README.md +31 -0
  16. data/vendor/schemas/kwalify/certification/v1.0.0.yaml +12 -0
  17. data/vendor/schemas/kwalify/component/test_data_validity.py +25 -0
  18. data/vendor/schemas/kwalify/component/v1.0.0.yaml +100 -0
  19. data/vendor/schemas/kwalify/component/v2.0.0.yaml +100 -0
  20. data/vendor/schemas/kwalify/component/v3.0.0.yaml +112 -0
  21. data/vendor/schemas/kwalify/component/v3.1.0.yaml +138 -0
  22. data/vendor/schemas/kwalify/opencontrol/v1.0.0.yaml +67 -0
  23. data/vendor/schemas/kwalify/requirements.txt +3 -0
  24. data/vendor/schemas/kwalify/standard/v1.0.0.yaml +14 -0
  25. data/vendor/schemas/transformation-scripts/utils.py +12 -0
  26. data/vendor/schemas/transformation-scripts/v1_example.yaml +40 -0
  27. data/vendor/schemas/transformation-scripts/v1_from_v2_example.yaml +41 -0
  28. data/vendor/schemas/transformation-scripts/v1_to_v2.py +75 -0
  29. data/vendor/schemas/transformation-scripts/v2_example.yaml +45 -0
  30. data/vendor/schemas/transformation-scripts/v2_from_v1_example.yaml +45 -0
  31. data/vendor/schemas/transformation-scripts/v2_to_v1.py +74 -0
  32. metadata +320 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f5809df9b521e096796e994cacf885be8dd2d41b
4
+ data.tar.gz: 4b1b9250c44fbc75d3a2b941003de47a5f0def13
5
+ SHA512:
6
+ metadata.gz: 27353289411c6cf7bd42794274c6a134a89c51b3cf7555c6bafc047ec2bbfce4b743760c4719a58451f2e9d3b9c8495437e609c6687c41bef4448b91928f57ba
7
+ data.tar.gz: 722a2e65f5f4c6aaa2a8d7806f34669513e195cde7fd654927d3dd514427c0d88286de961abbbd73ac7813f29ea380136ca19796687601ca701fd3ada2fb1d4d
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2019 Center for Medicare Services
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ [![CircleCI](https://circleci.com/gh/huge-robot/opencontrol-linter.svg?style=svg&circle-token=7873c3440387ef3e3b04964f5c51a15f7e3f26de)](https://circleci.com/gh/huge-robot/opencontrol-linter)
2
+
3
+
4
+ **Open Control Linter** is a linter for the OpenControl standard of security controls.
5
+ Use it to check the correctness of opencontrols components, standards and certifications quickly.
6
+
7
+ To find out more about opencontrol see:
8
+ http://opencontrol.cfapps.io/
9
+
10
+ ## Installation
11
+
12
+ ```sh
13
+ $ gem install opencontrol-linter
14
+ ```
15
+
16
+ If you'd rather install Open Control Linter using `bundler`, don't require it in your `Gemfile`:
17
+
18
+ ```rb
19
+ gem 'opencontrol-linter', require: false
20
+ ```
21
+
22
+ ## Quickstart
23
+
24
+ Just type `opencontrol-linter` in a control project root directory.
25
+
26
+ ```
27
+ $ cd awesome/opencontrols/
28
+ $ opencontrol-linter
29
+ ```
30
+
31
+ ## Documentation
32
+
33
+ Detailed command line arguments
34
+
35
+ ```
36
+ usage: opencontrol-linter
37
+
38
+ optional arguments:
39
+ -h, --help show this help message and exit
40
+ -c, --components
41
+ Specify component files should be checked. Defaults to
42
+ true. Searches ./**/component.yaml or the search you
43
+ optionally specify.
44
+ -n, --certifications
45
+ Specify certification (eg FISMA high)files should be
46
+ checked. Defaults to true. Searches
47
+ ./certifications/*.yaml or the search you optionally
48
+ specify.
49
+ -s, --standards
50
+ Specify standard files (eg NIST 800.53) should be
51
+ checked. Defaults to true. Searches ./standards/*.yaml
52
+ or the search you optionally specify.
53
+ -a, --all Run all types of validations (this is the default).
54
+ -v, --version Show the version of this utility.
55
+
56
+
57
+ ```
58
+
59
+ Usage examples
60
+
61
+ ```
62
+ # lint all components, standards and certifications in the current directory
63
+ opencontrol-linter
64
+
65
+ # lint all components subdir components
66
+ opencontrol-linter --components './components/**/component.yaml'
67
+
68
+ # lint all standards files found
69
+ opencontrol-linter --standards
70
+
71
+ # lint one component
72
+ opencontrol-linter --components './components/AU_policy/component.yaml'
73
+
74
+ ```
75
+
76
+ ## Compatibility
77
+
78
+ Open Control Linter supports the following Open Control schemas:
79
+
80
+ - Component: (all v1.0 through v3.1)
81
+ - Standard: (all v1.0 through v1.0)
82
+ - Certification: (all v1.0 through v1.0)
83
+
84
+ ## Related
85
+ http://opencontrol.cfapps.io/
86
+ https://github.com/opencontrol
87
+
88
+ ## Team
89
+
90
+ Here's a list of Open Control Linter's core developers:
91
+
92
+ * [Adrian Kierman](https://github.com/adriankierman)
93
+ * James Connor
94
+
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift("#{__dir__}/../lib")
5
+
6
+ require 'opencontrol'
7
+
8
+ Opencontrol::CLI.run_with_args(ARGV)
@@ -0,0 +1,3 @@
1
+ require_relative 'opencontrol/version'
2
+ require_relative 'opencontrol/messages'
3
+ require_relative 'opencontrol/cli'
@@ -0,0 +1,231 @@
1
+ require 'kwalify'
2
+ require 'yaml'
3
+ require 'opencontrol'
4
+ require 'rationalist'
5
+ require 'colorize'
6
+ require 'pp'
7
+
8
+ # frozen_string_literal: true
9
+
10
+ module Opencontrol
11
+ # This module holds the Opencontrol Linter Command Line Interface.
12
+ module CLI
13
+ USAGE_TEXT = <<USAGE_TEXT.freeze
14
+ usage: opencontrol-linter
15
+
16
+ optional arguments:
17
+ -h, --help show this help message and exit
18
+ -c, --components
19
+ Specify component files should be checked. Defaults to
20
+ true. Searches ./**/component.yaml or the search you
21
+ optionally specify.
22
+ -n, --certifications
23
+ Specify certification (eg FISMA high)files should be
24
+ checked. Defaults to true. Searches
25
+ ./certifications/*.yaml or the search you optionally
26
+ specify.
27
+ -s, --standards
28
+ Specify standard files (eg NIST 800.53) should be
29
+ checked. Defaults to true. Searches ./standards/*.yaml
30
+ or the search you optionally specify.
31
+ -a, --all Run all types of validations (this is the default).
32
+ -v, --version Show the version of this utility.
33
+
34
+ Usage examples:
35
+
36
+ # lint all components, standards and certifications in the current directory
37
+ opencontrol-linter
38
+
39
+ # lint all components subdir components
40
+ opencontrol-linter --components './components/**/component.yaml'
41
+
42
+ # lint all standards files found
43
+ opencontrol-linter --standards
44
+
45
+ # lint one component
46
+ opencontrol-linter --components './components/AU_policy/component.yaml'
47
+ USAGE_TEXT
48
+
49
+ DEFAULT_SPECIFICATION = {
50
+ action: :run,
51
+ targets: [
52
+ {
53
+ type: :components,
54
+ pattern: '**/component.yaml'
55
+ },
56
+ {
57
+ type: :standards,
58
+ pattern: './standards/*.yaml'
59
+ },
60
+ {
61
+ type: :certifications,
62
+ pattern: './certifications/*.yaml'
63
+ }
64
+ ]
65
+ }.freeze
66
+
67
+ def self.show_help
68
+ puts USAGE_TEXT
69
+ 0 # exit with no error
70
+ end
71
+
72
+ def self.show_version
73
+ puts 'Opencontrol linter version: v' + Opencontrol::Version.version
74
+ puts 'CMS 2019 Adrian Kierman '
75
+ 0 # exit with no error
76
+ end
77
+
78
+ # @param [String] version
79
+ def self.find_schema(type, version)
80
+ dir = __dir__
81
+ case type
82
+ when :components
83
+ "#{dir}/../../vendor/schemas/kwalify/component/v#{version}.yaml"
84
+ when :standards
85
+ "#{dir}/../../vendor/schemas/kwalify/standard/v#{version}.yaml"
86
+ when :certifications
87
+ "#{dir}/../../vendor/schemas/kwalify/certification/v#{version}.yaml"
88
+ else
89
+ throw "Unknown type of schema specified #{type} " \
90
+ "tried to get schema version #{version}"
91
+ end
92
+ end
93
+
94
+ def self.load_schema(schema_file)
95
+ ## load schema data
96
+ # Kwalify::Yaml.load_file(schema_file)
97
+ ## or
98
+ YAML.load_file(schema_file)
99
+ end
100
+
101
+ def self.show_issues(issues, filename)
102
+ if issues && !issues.empty?
103
+ puts "✗ #{filename}".red
104
+ issues.each do |issue|
105
+ puts Opencontrol::Messages.detail(issue).yellow
106
+ end
107
+ else
108
+ puts "✓ #{filename}".green
109
+ end
110
+ end
111
+
112
+ def self.schema_for_document(type, document)
113
+ version = document['schema_version'] || '1.0.0'
114
+ schema_file = find_schema(type, version)
115
+ load_schema(schema_file)
116
+ end
117
+
118
+ def self.targets_for_type(type, specification)
119
+ specification[:targets].select { |t| t[:type] == type }
120
+ end
121
+
122
+ def self.default_pattern_for_type(type)
123
+ targets_for_type(type, DEFAULT_SPECIFICATION).first[:pattern]
124
+ end
125
+
126
+ def self.add_target(type, opts, specification)
127
+ # pick a reasonable default
128
+ use_defaults = false
129
+ use_defaults = default_pattern_for_type(type) if opts[type] == true
130
+ specification[:targets].push(
131
+ type: type,
132
+ pattern: use_defaults || opts[type]
133
+ )
134
+ end
135
+
136
+ def self.validate(type, filename)
137
+ ## load document
138
+ # document = Kwalify::Yaml.load_file(filename)
139
+ ## or
140
+ document = YAML.load_file(filename)
141
+ schema = schema_for_document(type, document)
142
+
143
+ validator = Kwalify::Validator.new(schema)
144
+ validator.validate(document)
145
+ end
146
+
147
+ def self.files_not_found_issue
148
+ Kwalify::BaseError.new(
149
+ 'No validation files found for the pattern supplied. \
150
+ Adding an issue to avoid failing silently.',
151
+ nil,
152
+ nil,
153
+ nil,
154
+ :linter_files_not_found_issue
155
+ )
156
+ end
157
+
158
+ def self.validate_target(target)
159
+ filenames = Dir[target[:pattern]]
160
+ if filenames.empty?
161
+ issues = [files_not_found_issue]
162
+ show_issues(issues, target[:pattern])
163
+ return issues
164
+ end
165
+ filenames.collect do |filename|
166
+ issues = validate(target[:type], filename)
167
+ show_issues(issues, filename)
168
+ issues
169
+ end
170
+ end
171
+
172
+ def self.validate_all(specification)
173
+ specification[:targets].collect do |target|
174
+ validate_target(target)
175
+ end.flatten
176
+ end
177
+
178
+ def self.should_lint?(opts)
179
+ !(opts[:version] || opts[:help])
180
+ end
181
+
182
+ def self.all_targets_selected?(opts, specification)
183
+ opts[:all] || specification[:targets].empty?
184
+ end
185
+
186
+ def self.use_default?(opts, specification)
187
+ all_targets_selected?(opts, specification) && should_lint?(opts)
188
+ end
189
+
190
+ ALIASES = {
191
+ components: %w[component c],
192
+ standards: %w[standard s],
193
+ certifications: %w[certification n],
194
+ all: 'a',
195
+ help: 'h',
196
+ version: 'v'
197
+ }.freeze
198
+
199
+ def self.parse_args(arguments)
200
+ opts = Rationalist.parse(arguments, alias: ALIASES)
201
+ specification = {
202
+ action: :run,
203
+ targets: []
204
+ }
205
+ specification[:action] = :version if opts[:version]
206
+ specification[:action] = :help if opts[:help]
207
+ add_target(:components, opts, specification) if opts[:components]
208
+ add_target(:standards, opts, specification) if opts[:standards]
209
+ add_target(:certifications, opts, specification) if opts[:certifications]
210
+ specification = DEFAULT_SPECIFICATION if use_default?(opts, specification)
211
+ specification
212
+ end
213
+
214
+ def self.run(specification)
215
+ issues = validate_all(specification)
216
+ if !issues.empty?
217
+ puts "Complete. #{issues.length} issues found.".red
218
+ else
219
+ puts 'Complete. No problems found.'.green
220
+ end
221
+ issues.length
222
+ end
223
+
224
+ def self.run_with_args(args)
225
+ specification = parse_args(args)
226
+ exit(run(specification)) if specification[:action] == :run
227
+ show_version if specification[:action] == :version
228
+ show_help if specification[:action] == :help
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kwalify'
4
+
5
+ module Opencontrol
6
+ # This module holds the Opencontrol Linter detailed issue messages.
7
+ module Messages
8
+ def self.detail(issue)
9
+ case issue.error_symbol
10
+ when :enum_notexist
11
+ <<-MESSAGE
12
+ At: YAML path #{issue.path}.
13
+ Message: #{issue.message}
14
+ Expected: one of #{issue.rule.enum}.
15
+ Actual: The value '#{issue.value}' was found.
16
+ To fix this: Use one of #{issue.rule.enum}
17
+ instead of the value '#{issue.value}'
18
+ MESSAGE
19
+ when :key_undefined
20
+ <<-MESSAGE
21
+ At: YAML path #{issue.path}.
22
+ Expected: A key allowed by the schema.
23
+ Actual: A key was found that is not defined in the schema (#{issue.path}).
24
+ To fix this: Its possible the key found is a typo,
25
+ Remove #{issue.path} or correct the key.
26
+ MESSAGE
27
+ else
28
+ <<-MESSAGE
29
+ At: YAML path #{issue.path}.
30
+ Message: #{issue.message}
31
+ MESSAGE
32
+ end
33
+ end
34
+
35
+ def self.verbose(issue)
36
+ <<-MESSAGE
37
+ At: YAML path #{issue.path}.
38
+ Message: #{issue.message}
39
+ Rule: #{issue.rule.to_yaml}
40
+ Value: #{issue.value}
41
+ Symbol: #{issue.error_symbol}
42
+ MESSAGE
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Opencontrol
4
+ # This module holds the Opencontrol Linter version information.
5
+ module Version
6
+ STRING = '0.1'.freeze
7
+
8
+ MSG = '%<version>s (using Parser %<parser_version>s, running on ' \
9
+ '%<ruby_engine>s %<ruby_version>s %<ruby_platform>s)'.freeze
10
+
11
+ def self.version(debug = false)
12
+ if debug
13
+ require 'kwalify'
14
+ format(MSG, version: STRING, parser_version: Kwalify::VERSION,
15
+ ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION,
16
+ ruby_platform: RUBY_PLATFORM)
17
+ else
18
+ STRING
19
+ end
20
+ end
21
+ end
22
+ end
data/vendor/README.md ADDED
@@ -0,0 +1,9 @@
1
+ - Schemas
2
+
3
+ A project of 18F
4
+
5
+ General Services Administration of the United States
6
+
7
+ https://github.com/opencontrol/schemas
8
+
9
+ Included here in vendorized form to allow easy distribution.