Browse Source

Refactor checks & states

aeris 1 year ago
parent
commit
2b8f102bb5

+ 1
- 1
cryptcheck.gemspec View File

@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4 4
 
5 5
 Gem::Specification.new do |spec|
6 6
 	spec.name    = 'cryptcheck'
7
-	spec.version = '1.0.0'
7
+	spec.version = '2.0.0'
8 8
 	spec.authors = ['Aeris']
9 9
 	spec.email   = ['aeris+tls@imirhil.fr']
10 10
 

+ 1
- 1
lib/cryptcheck/fixture.rb View File

@@ -6,7 +6,7 @@ class String
6 6
 			error:    :red,
7 7
 			warning:  :light_red,
8 8
 			good:     :green,
9
-			perfect:  :blue,
9
+			great:  :blue,
10 10
 			best:     :magenta,
11 11
 			unknown:  { background: :black }
12 12
 	}

+ 1
- 1
lib/cryptcheck/logger.rb View File

@@ -1,11 +1,11 @@
1 1
 module CryptCheck
2 2
 	class Logger
3 3
 		LEVELS  = %i(trace debug info warning error fatal none)
4
-		@@level = :info
5 4
 
6 5
 		def self.level=(level)
7 6
 			@@level = level.to_sym
8 7
 		end
8
+		self.level = ENV.fetch 'LOG', :info
9 9
 
10 10
 		def self.log(level, string=nil, output: $stdout, &block)
11 11
 			return unless enabled? level

+ 54
- 36
lib/cryptcheck/state.rb View File

@@ -1,15 +1,31 @@
1 1
 module CryptCheck
2 2
 	module State
3 3
 		def states
4
-			@status ||= calculate_states
4
+			# Remove duplicated test for each level
5
+			@states ||= self.checks.group_by { |c| c[1] }.collect do |level, checks|
6
+				states = checks.group_by(&:first).collect do |name, checks|
7
+					states = checks.collect &:last
8
+					# true > false > nil
9
+					state  = if states.include? true
10
+								 true
11
+							 elsif states.include? false
12
+								 false
13
+							 else
14
+								 nil
15
+							 end
16
+					[name, state]
17
+				end.to_h
18
+				[level, states]
19
+			end.to_h
5 20
 		end
6 21
 
7 22
 		def status
8
-			State.status self.states.reject { |_, v| v.empty? }.keys
23
+			@status ||= State.status self.checks.select { |c| c.last == true }.collect { |c| c[1] }
9 24
 		end
10 25
 
11
-		LEVELS   = %i(best perfect good warning error critical).freeze
12
-		PROBLEMS = %i(warning error critical).freeze
26
+		BADS   = %i(critical error warning).freeze
27
+		GOODS  = %i(good great best).freeze
28
+		LEVELS = (BADS + GOODS).freeze
13 29
 
14 30
 		extend Enumerable
15 31
 
@@ -32,7 +48,7 @@ module CryptCheck
32 48
 
33 49
 		def self.problem(states)
34 50
 			states = self.convert states
35
-			self.min PROBLEMS, states
51
+			self.min BADS, states
36 52
 		end
37 53
 
38 54
 		def self.sort(states)
@@ -40,7 +56,9 @@ module CryptCheck
40 56
 		end
41 57
 
42 58
 		def self.compare(a, b)
43
-			LEVELS.find_index(a.status) <=> LEVELS.find_index(b.status)
59
+			a = LEVELS.find_index(a.status) || (LEVELS.size - 1) / 2.0
60
+			b = LEVELS.find_index(b.status) || (LEVELS.size - 1) / 2.0
61
+			a <=> b
44 62
 		end
45 63
 
46 64
 		def performed_checks
@@ -48,6 +66,11 @@ module CryptCheck
48 66
 			@performed_checks
49 67
 		end
50 68
 
69
+		protected
70
+		def checks
71
+			@checks ||= self.available_checks.collect { |c| perform_check c }.flatten(1) + children.collect(&:checks).flatten(1)
72
+		end
73
+
51 74
 		private
52 75
 		def self.convert(status)
53 76
 			status = [status] unless status.respond_to? :first
@@ -58,6 +81,11 @@ module CryptCheck
58 81
 
59 82
 		def self.min(levels, states)
60 83
 			return nil if states.empty?
84
+			(levels & states).first
85
+		end
86
+
87
+		def self.max(levels, states)
88
+			return nil if states.empty?
61 89
 			(levels & states).last
62 90
 		end
63 91
 
@@ -74,37 +102,27 @@ module CryptCheck
74 102
 		end
75 103
 
76 104
 		def perform_check(check)
77
-			name, check, level = check
78
-			result             = check.call self
79
-			return nil unless result
80
-			level ||= result
81
-			[level, name]
82
-		end
83
-
84
-		def personal_states
85
-			states           = State.empty
86
-			performed_checks = checks
87
-			performed_checks.each do |check|
88
-				level, name = perform_check check
89
-				next unless level
90
-				states[level] << name
105
+			name, levels, check = check
106
+			result              = check.call self
107
+			case levels
108
+				when Symbol # Expected result is true/false/nil
109
+					return [[name, levels, result]]
110
+				else # Expected result is the best/worst case
111
+					# N/A, so return all levels as N/A
112
+					return levels.collect { |l| [name, l, nil] } if result.nil?
113
+
114
+					checks = []
115
+					if BADS.include? result
116
+						checks += (GOODS & levels).collect { |l| [name, l, false] }
117
+						index  = BADS.index result
118
+						checks += (BADS & levels).collect { |l| [name, l, BADS.index(l) >= index] }
119
+					else
120
+						checks += (BADS & levels).collect { |l| [name, l, false] }
121
+						index  = GOODS.index result
122
+						checks += (GOODS & levels).collect { |l| [name, l, GOODS.index(l) <= index] }
123
+					end
124
+					return checks
91 125
 			end
92
-
93
-			performed_checks  = [
94
-					performed_checks
95
-							.collect { |n, _, l| [l, n] }
96
-							.group_by(&:first)
97
-							.map { |k, v| [k, v.collect(&:last)] }.to_h
98
-			] + children.collect(&:performed_checks)
99
-			@performed_checks = State.merge *performed_checks
100
-
101
-			states
102
-		end
103
-
104
-		def calculate_states
105
-			children_states = children.collect(&:states)
106
-			states          = [personal_states] + children_states
107
-			State.merge *states
108 126
 		end
109 127
 	end
110 128
 end

+ 3
- 2
lib/cryptcheck/tls/cert.rb View File

@@ -107,15 +107,16 @@ module CryptCheck
107 107
 				@cert.issuer
108 108
 			end
109 109
 
110
+			protected
110 111
 			include State
111 112
 
112 113
 			CHECKS = WEAK_SIGN.collect do |level, hashes|
113 114
 				hashes.collect do |hash|
114
-					["#{hash}_sign".to_sym, -> (s) { s.send "#{hash}?" }, level]
115
+					["#{hash}_sign".to_sym, level, -> (s) { s.send "#{hash}?" }]
115 116
 				end
116 117
 			end.flatten(1).freeze
117 118
 
118
-			def checks
119
+			def available_checks
119 120
 				CHECKS
120 121
 			end
121 122
 

+ 16
- 18
lib/cryptcheck/tls/cipher.rb View File

@@ -104,7 +104,7 @@ module CryptCheck
104 104
 			def to_s(type = :long)
105 105
 				case type
106 106
 					when :long
107
-						states = self.states.collect { |k, vs| vs.collect { |v| v.to_s.colorize k } }.flatten.join ' '
107
+						states = self.states.collect { |k, vs| vs.select { |_, c| c == true }.collect { |v| v.first.to_s.colorize k } }.flatten.join ' '
108 108
 						"#{@method} #{@name.colorize self.status} [#{states}]"
109 109
 					when :short
110 110
 						@name.colorize self.status
@@ -227,28 +227,26 @@ module CryptCheck
227 227
 				end
228 228
 			end
229 229
 
230
+			protected
230 231
 			include State
231 232
 
232 233
 			CHECKS = [
233
-					[:dss, -> (c) { c.dss? }, :critical],
234
-					[:anonymous, -> (c) { c.anonymous? }, :critical],
235
-					[:null, -> (c) { c.null? }, :critical],
236
-					[:export, -> (c) { c.export? }, :critical],
237
-					[:des, -> (c) { c.des? }, :critical],
238
-					[:md5, -> (c) { c.md5? }, :critical],
239
-
240
-					[:rc4, -> (c) { c.rc4? }, :error],
241
-					[:sweet32, -> (c) { c.sweet32? }, :error],
242
-
243
-					[:no_pfs, -> (c) { not c.pfs? }, :warning],
244
-					[:pfs, -> (c) { c.pfs? }, :good],
245
-					[:dhe, -> (c) { c.dhe? }, :warning],
246
-					[:ecdhe, -> (c) { c.ecdhe? }, :good],
247
-
248
-					[:aead, -> (c) { c.aead? }, :good]
234
+					[:dss, :critical, -> (c) { c.dss? }],
235
+					[:anonymous, :critical, -> (c) { c.anonymous? }],
236
+					[:null, :critical, -> (c) { c.null? }],
237
+					[:export, :critical, -> (c) { c.export? }],
238
+					[:des, :critical, -> (c) { c.des? }],
239
+					[:md5, :critical, -> (c) { c.md5? }],
240
+					[:rc4, :critical, -> (c) { c.rc4? }],
241
+					[:sweet32, :critical, -> (c) { c.sweet32? }],
242
+
243
+					[:pfs, :error, -> (c) { not c.pfs? }],
244
+					[:dhe, :warning, -> (c) { c.dhe? }],
245
+
246
+					[:aead, :good, -> (c) { c.aead? }]
249 247
 			].freeze
250 248
 
251
-			def checks
249
+			def available_checks
252 250
 				CHECKS
253 251
 			end
254 252
 

+ 3
- 1
lib/cryptcheck/tls/curve.rb View File

@@ -40,11 +40,13 @@ module CryptCheck
40 40
 				end
41 41
 			end
42 42
 
43
+			protected
43 44
 			include State
44 45
 
45 46
 			CHECKS = [].freeze
46 47
 
47
-			def checks
48
+			protected
49
+			def available_checks
48 50
 				CHECKS
49 51
 			end
50 52
 		end

+ 13
- 8
lib/cryptcheck/tls/fixture.rb View File

@@ -17,10 +17,11 @@ class ::OpenSSL::PKey::EC
17 17
 		"ECC #{self.size} bits"
18 18
 	end
19 19
 
20
+	protected
20 21
 	include ::CryptCheck::State
21 22
 
22 23
 	CHECKS = [
23
-			[:weak_key, -> (s) do
24
+			[:ecc, %i(critical error warning), -> (s) do
24 25
 				case s.size
25 26
 					when 0...160
26 27
 						:critical
@@ -32,7 +33,7 @@ class ::OpenSSL::PKey::EC
32 33
 			end]
33 34
 	].freeze
34 35
 
35
-	def checks
36
+	def available_checks
36 37
 		CHECKS
37 38
 	end
38 39
 end
@@ -50,10 +51,11 @@ class ::OpenSSL::PKey::RSA
50 51
 		"RSA #{self.size} bits"
51 52
 	end
52 53
 
54
+	protected
53 55
 	include ::CryptCheck::State
54 56
 
55 57
 	CHECKS = [
56
-			[:weak_key, -> (s) do
58
+			[:rsa, %i(critical error), -> (s) do
57 59
 				case s.size
58 60
 					when 0...1024
59 61
 						:critical
@@ -63,7 +65,7 @@ class ::OpenSSL::PKey::RSA
63 65
 			end]
64 66
 	].freeze
65 67
 
66
-	def checks
68
+	def available_checks
67 69
 		CHECKS
68 70
 	end
69 71
 end
@@ -84,10 +86,11 @@ class ::OpenSSL::PKey::DSA
84 86
 	include ::CryptCheck::State
85 87
 
86 88
 	CHECKS = [
87
-			[:weak_key, -> (_) { :critical }]
89
+			[:dsa, :critical, -> (_) { true }]
88 90
 	].freeze
89 91
 
90
-	def checks
92
+	protected
93
+	def available_checks
91 94
 		CHECKS
92 95
 	end
93 96
 end
@@ -105,10 +108,11 @@ class ::OpenSSL::PKey::DH
105 108
 		"DH #{self.size} bits"
106 109
 	end
107 110
 
111
+	protected
108 112
 	include ::CryptCheck::State
109 113
 
110 114
 	CHECKS = [
111
-			[:weak_dh, -> (s) do
115
+			[:dh, %i(critical error), -> (s) do
112 116
 				case s.size
113 117
 					when 0...1024
114 118
 						:critical
@@ -118,7 +122,8 @@ class ::OpenSSL::PKey::DH
118 122
 			end]
119 123
 	].freeze
120 124
 
121
-	def checks
125
+	protected
126
+	def available_checks
122 127
 		CHECKS
123 128
 	end
124 129
 end

+ 6
- 2
lib/cryptcheck/tls/grade.rb View File

@@ -16,7 +16,7 @@ module CryptCheck
16 16
 							when 'A', 'A+'
17 17
 								:best
18 18
 							when 'B', 'B+'
19
-								:perfect
19
+								:great
20 20
 							when 'C', 'C+'
21 21
 								:good
22 22
 							when 'E'
@@ -32,6 +32,10 @@ module CryptCheck
32 32
 				Logger.info { "Grade : #{self.grade.colorize color }" }
33 33
 			end
34 34
 
35
+			def to_h
36
+				{ checks: @checks, states: @states }
37
+			end
38
+
35 39
 			private
36 40
 			def calculate_grade
37 41
 				return 'V' unless @server.valid?
@@ -47,7 +51,7 @@ module CryptCheck
47 51
 				end
48 52
 
49 53
 				[[:good, 'D', 'C'],
50
-				 [:perfect, 'C', 'B'],
54
+				 [:great, 'C', 'B'],
51 55
 				 [:best, 'B', 'A']].each do |type, score1, score2|
52 56
 					expected = @checks[type]
53 57
 					unless expected.empty?

+ 26
- 14
lib/cryptcheck/tls/host.rb View File

@@ -44,25 +44,37 @@ module CryptCheck
44 44
 					end
45 45
 					[[@hostname, ip, @port], result]
46 46
 				end.to_h
47
+			# rescue StandardError
48
+			# 	raise
47 49
 			rescue => e
48 50
 				@error = e
49 51
 			end
50 52
 
51
-			def to_json
52
-				JSON.generate(@servers.collect do |host, result|
53
-					hostname, ip, _ = host
54
-					json            = {
55
-							hostname: hostname,
56
-							ip:       ip,
57
-					}
58
-					case result
59
-						when Grade
60
-							json[:result] = result.to_json
61
-						else
62
-							json[:error] = result.message
53
+			def to_h
54
+				target = {
55
+						target: { hostname: @hostname, port: @port },
56
+				}
57
+				if @error
58
+					target[:error] = @error
59
+				else
60
+					target[:hosts] = @servers.collect do |host, grade|
61
+						hostname, ip, port = host
62
+						host               = {
63
+								hostname: hostname,
64
+								ip:       ip,
65
+								port:     port
66
+						}
67
+						case grade
68
+							when Grade
69
+								host[:analysis] = grade.server.to_h
70
+								host[:status]   = grade.to_h
71
+							else
72
+								host[:error] = grade.message
73
+						end
74
+						host
63 75
 					end
64
-					json
65
-				end)
76
+				end
77
+				target
66 78
 			end
67 79
 
68 80
 			private

+ 4
- 4
lib/cryptcheck/tls/https/server.rb View File

@@ -48,11 +48,11 @@ module CryptCheck
48 48
 					hsts? and @hsts >= LONG_HSTS
49 49
 				end
50 50
 
51
-				def checks
51
+				protected
52
+				def available_checks
52 53
 					super + [
53
-							[:hsts, -> (s) { s.hsts? }, :good],
54
-							[:hsts_long, -> (s) { s.hsts_long? }, :perfect],
55
-							#[:must_staple, -> (s) { s.must_staple? }, :best],
54
+							[:hsts, %i(warning good great), -> (s) { s.hsts_long? ? :great : s.hsts? ? :good : :warning }],
55
+							#[:must_staple, :best, -> (s) { s.must_staple? }],
56 56
 					]
57 57
 				end
58 58
 			end

+ 6
- 4
lib/cryptcheck/tls/method.rb View File

@@ -36,12 +36,14 @@ module CryptCheck
36 36
 			include State
37 37
 
38 38
 			CHECKS = [
39
-					[:sslv2, -> (s) { s == :SSLv2 }, :critical],
40
-					[:sslv3, -> (s) { s == :SSLv3 }, :critical],
41
-					[:tlsv1_2, -> (s) { s == :TLSv1_2 }, :good]
39
+					[:sslv2, :critical, -> (s) { s == :SSLv2 }],
40
+					[:sslv3, :critical, -> (s) { s == :SSLv3 }],
41
+					[:tlsv1_0, :error, -> (s) { s == :TLSv1 }],
42
+					[:tlsv1_1, :warning, -> (s) { s == :TLSv1_1 }]
42 43
 			]
43 44
 
44
-			def checks
45
+			protected
46
+			def available_checks
45 47
 				CHECKS
46 48
 			end
47 49
 		end

+ 12
- 13
lib/cryptcheck/tls/server.rb View File

@@ -61,24 +61,23 @@ module CryptCheck
61 61
 				@trusted
62 62
 			end
63 63
 
64
+			def to_h
65
+
66
+			end
67
+
68
+			protected
64 69
 			include State
65 70
 
66 71
 			CHECKS = [
67
-					[:tlsv1_2_only, -> (s) { s.tlsv1_2_only? }, :perfect],
68
-					[:pfs_only, -> (s) { s.pfs_only? }, :perfect],
69
-					[:ecdhe_only, -> (s) { s.ecdhe_only? }, :perfect],
70
-					#[:aead_only, -> (s) { s.aead_only? }, :best],
72
+					[:fallback_scsv, :good, -> (s) { s.fallback_scsv? }]
73
+			# [:tlsv1_2_only, -> (s) { s.tlsv1_2_only? }, :great],
74
+			# [:pfs_only, -> (s) { s.pfs_only? }, :great],
75
+			# [:ecdhe_only, -> (s) { s.ecdhe_only? }, :great],
76
+			#[:aead_only, -> (s) { s.aead_only? }, :best],
71 77
 			].freeze
72 78
 
73
-			def checks
74
-				checks = CHECKS
75
-				unless self.fallback_scsv? == nil
76
-					checks += [
77
-							[:no_fallback_scsv, -> (s) { not s.fallback_scsv? }, :error],
78
-							[:fallback_scsv, -> (s) { s.fallback_scsv? }, :good]
79
-					]
80
-				end
81
-				checks
79
+			def available_checks
80
+				CHECKS
82 81
 			end
83 82
 
84 83
 			def children

+ 145
- 48
spec/cryptcheck/status_spec.rb View File

@@ -13,7 +13,7 @@ describe CryptCheck::State do
13 13
 					[:critical, :warning]  => :critical,
14 14
 					[:critical, nil]       => :critical,
15 15
 					[:critical, :good]     => :critical,
16
-					[:critical, :perfect]  => :critical,
16
+					[:critical, :great]    => :critical,
17 17
 					[:critical, :best]     => :critical,
18 18
 
19 19
 					[:error, :critical]    => :critical,
@@ -21,7 +21,7 @@ describe CryptCheck::State do
21 21
 					[:error, :warning]     => :error,
22 22
 					[:error, nil]          => :error,
23 23
 					[:error, :good]        => :error,
24
-					[:error, :perfect]     => :error,
24
+					[:error, :great]       => :error,
25 25
 					[:error, :best]        => :error,
26 26
 
27 27
 					[:warning, :critical]  => :critical,
@@ -29,7 +29,7 @@ describe CryptCheck::State do
29 29
 					[:warning, :warning]   => :warning,
30 30
 					[:warning, nil]        => :warning,
31 31
 					[:warning, :good]      => :warning,
32
-					[:warning, :perfect]   => :warning,
32
+					[:warning, :great]     => :warning,
33 33
 					[:warning, :best]      => :warning,
34 34
 
35 35
 					[:good, :critical]     => :critical,
@@ -37,23 +37,23 @@ describe CryptCheck::State do
37 37
 					[:good, :warning]      => :warning,
38 38
 					[:good, nil]           => :good,
39 39
 					[:good, :good]         => :good,
40
-					[:good, :perfect]      => :good,
40
+					[:good, :great]        => :good,
41 41
 					[:good, :best]         => :good,
42 42
 
43
-					[:perfect, :critical]  => :critical,
44
-					[:perfect, :error]     => :error,
45
-					[:perfect, :warning]   => :warning,
46
-					[:perfect, nil]        => :perfect,
47
-					[:perfect, :good]      => :good,
48
-					[:perfect, :perfect]   => :perfect,
49
-					[:perfect, :best]      => :perfect,
43
+					[:great, :critical]    => :critical,
44
+					[:great, :error]       => :error,
45
+					[:great, :warning]     => :warning,
46
+					[:great, nil]          => :great,
47
+					[:great, :good]        => :good,
48
+					[:great, :great]       => :great,
49
+					[:great, :best]        => :great,
50 50
 
51 51
 					[:best, :critical]     => :critical,
52 52
 					[:best, :error]        => :error,
53 53
 					[:best, :warning]      => :warning,
54 54
 					[:best, nil]           => :best,
55 55
 					[:best, :good]         => :good,
56
-					[:best, :perfect]      => :perfect,
56
+					[:best, :great]        => :great,
57 57
 					[:best, :best]         => :best
58 58
 			}.each do |levels, result|
59 59
 				got = CryptCheck::State.status levels
@@ -76,7 +76,7 @@ describe CryptCheck::State do
76 76
 					[:critical, :warning]  => :critical,
77 77
 					[:critical, nil]       => :critical,
78 78
 					[:critical, :good]     => :critical,
79
-					[:critical, :perfect]  => :critical,
79
+					[:critical, :great]    => :critical,
80 80
 					[:critical, :best]     => :critical,
81 81
 
82 82
 					[:error, :critical]    => :critical,
@@ -84,7 +84,7 @@ describe CryptCheck::State do
84 84
 					[:error, :warning]     => :error,
85 85
 					[:error, nil]          => :error,
86 86
 					[:error, :good]        => :error,
87
-					[:error, :perfect]     => :error,
87
+					[:error, :great]       => :error,
88 88
 					[:error, :best]        => :error,
89 89
 
90 90
 					[:warning, :critical]  => :critical,
@@ -92,7 +92,7 @@ describe CryptCheck::State do
92 92
 					[:warning, :warning]   => :warning,
93 93
 					[:warning, nil]        => :warning,
94 94
 					[:warning, :good]      => :warning,
95
-					[:warning, :perfect]   => :warning,
95
+					[:warning, :great]     => :warning,
96 96
 					[:warning, :best]      => :warning,
97 97
 
98 98
 					[:good, :critical]     => :critical,
@@ -100,23 +100,23 @@ describe CryptCheck::State do
100 100
 					[:good, :warning]      => :warning,
101 101
 					[:good, nil]           => nil,
102 102
 					[:good, :good]         => nil,
103
-					[:good, :perfect]      => nil,
103
+					[:good, :great]        => nil,
104 104
 					[:good, :best]         => nil,
105 105
 
106
-					[:perfect, :critical]  => :critical,
107
-					[:perfect, :error]     => :error,
108
-					[:perfect, :warning]   => :warning,
109
-					[:perfect, nil]        => nil,
110
-					[:perfect, :good]      => nil,
111
-					[:perfect, :perfect]   => nil,
112
-					[:perfect, :best]      => nil,
106
+					[:great, :critical]    => :critical,
107
+					[:great, :error]       => :error,
108
+					[:great, :warning]     => :warning,
109
+					[:great, nil]          => nil,
110
+					[:great, :good]        => nil,
111
+					[:great, :great]       => nil,
112
+					[:great, :best]        => nil,
113 113
 
114 114
 					[:best, :critical]     => :critical,
115 115
 					[:best, :error]        => :error,
116 116
 					[:best, :warning]      => :warning,
117 117
 					[:best, nil]           => nil,
118 118
 					[:best, :good]         => nil,
119
-					[:best, :perfect]      => nil,
119
+					[:best, :great]        => nil,
120 120
 					[:best, :best]         => nil
121 121
 			}.each do |levels, result|
122 122
 				got = CryptCheck::State.problem levels
@@ -133,7 +133,6 @@ describe CryptCheck::State do
133 133
 
134 134
 	describe '#states' do
135 135
 		def match_states(actual, **expected)
136
-			expected = ::CryptCheck::State.empty.merge expected
137 136
 			expect(actual.states).to eq expected
138 137
 		end
139 138
 
@@ -141,7 +140,7 @@ describe CryptCheck::State do
141 140
 			Class.new do
142 141
 				include ::CryptCheck::State
143 142
 
144
-				def checks
143
+				def available_checks
145 144
 					[]
146 145
 				end
147 146
 			end.new
@@ -150,11 +149,11 @@ describe CryptCheck::State do
150 149
 			Class.new do
151 150
 				include ::CryptCheck::State
152 151
 
153
-				def checks
152
+				def available_checks
154 153
 					[
155
-							[:foo, -> (_) { true }, :critical],
156
-							[:bar, -> (_) { :error }],
157
-							[:baz, -> (_) { false }]
154
+							[:foo, :critical, -> (_) { true }],
155
+							[:bar, :error, -> (_) { true }],
156
+							[:baz, :warning, -> (_) { false }]
158 157
 					]
159 158
 				end
160 159
 			end.new
@@ -163,8 +162,8 @@ describe CryptCheck::State do
163 162
 			child = Class.new do
164 163
 				include ::CryptCheck::State
165 164
 
166
-				def checks
167
-					[[:bar, -> (_) { :error }]]
165
+				def available_checks
166
+					[[:bar, :error, -> (_) { true }]]
168 167
 				end
169 168
 			end.new
170 169
 			Class.new do
@@ -174,21 +173,21 @@ describe CryptCheck::State do
174 173
 					@child = child
175 174
 				end
176 175
 
177
-				def checks
178
-					[[:foo, -> (_) { :critical }]]
176
+				def available_checks
177
+					[[:foo, :critical, -> (_) { true }]]
179 178
 				end
180 179
 
181 180
 				def children
182 181
 					[@child]
183 182
 				end
184
-			end.new(child)
183
+			end.new child
185 184
 		end
186 185
 		let(:duplicated) do
187 186
 			child = Class.new do
188 187
 				include ::CryptCheck::State
189 188
 
190
-				def checks
191
-					[[:foo, -> (_) { :critical }]]
189
+				def available_checks
190
+					[[:foo, :error, -> (_) { true }]]
192 191
 				end
193 192
 			end.new
194 193
 			Class.new do
@@ -198,8 +197,8 @@ describe CryptCheck::State do
198 197
 					@child = child
199 198
 				end
200 199
 
201
-				def checks
202
-					[[:foo, -> (_) { :critical }]]
200
+				def available_checks
201
+					[[:foo, :critical, -> (_) { true }]]
203 202
 				end
204 203
 
205 204
 				def children
@@ -208,20 +207,118 @@ describe CryptCheck::State do
208 207
 			end.new(child)
209 208
 		end
210 209
 
210
+		it 'must return the level if single level specified' do
211
+			obj = Class.new do
212
+				include ::CryptCheck::State
213
+
214
+				def available_checks
215
+					[[:foo, :critical, -> (_) { true }]]
216
+				end
217
+			end.new
218
+			expect(obj.states).to eq({ critical: { foo: true } })
219
+
220
+			obj = Class.new do
221
+				include ::CryptCheck::State
222
+
223
+				def available_checks
224
+					[[:foo, :critical, -> (_) { false }]]
225
+				end
226
+			end.new
227
+			expect(obj.states).to eq({ critical: { foo: false } })
228
+
229
+			obj = Class.new do
230
+				include ::CryptCheck::State
231
+
232
+				def available_checks
233
+					[[:foo, :critical, -> (_) { nil }]]
234
+				end
235
+			end.new
236
+			expect(obj.states).to eq({ critical: { foo: nil } })
237
+		end
238
+
239
+		it 'must return all levels if multiple levels specified' do
240
+			obj = Class.new do
241
+				include ::CryptCheck::State
242
+
243
+				def available_checks
244
+					[[:foo, %i(critical error good great), -> (_) { :critical }]]
245
+				end
246
+			end.new
247
+			expect(obj.states).to eq({
248
+											 critical: { foo: true },
249
+											 error:    { foo: true },
250
+											 good:     { foo: false },
251
+											 great:    { foo: false } })
252
+
253
+			obj = Class.new do
254
+				include ::CryptCheck::State
255
+
256
+				def available_checks
257
+					[[:foo, %i(critical error good great), -> (_) { :error }]]
258
+				end
259
+			end.new
260
+			expect(obj.states).to eq({
261
+											 critical: { foo: false },
262
+											 error:    { foo: true },
263
+											 good:     { foo: false },
264
+											 great:    { foo: false } })
265
+
266
+
267
+			obj = Class.new do
268
+				include ::CryptCheck::State
269
+
270
+				def available_checks
271
+					[[:foo, %i(critical error good great), -> (_) { :great }]]
272
+				end
273
+			end.new
274
+			expect(obj.states).to eq({
275
+											 critical: { foo: false },
276
+											 error:    { foo: false },
277
+											 good:     { foo: true },
278
+											 great:    { foo: true } })
279
+
280
+
281
+			obj = Class.new do
282
+				include ::CryptCheck::State
283
+
284
+				def available_checks
285
+					[[:foo, %i(critical error good great), -> (_) { :good }]]
286
+				end
287
+			end.new
288
+			expect(obj.states).to eq({
289
+											 critical: { foo: false },
290
+											 error:    { foo: false },
291
+											 good:     { foo: true },
292
+											 great:    { foo: false } })
293
+
294
+			obj = Class.new do
295
+				include ::CryptCheck::State
296
+
297
+				def available_checks
298
+					[[:foo, %i(critical error good great), -> (_) { nil }]]
299
+				end
300
+			end.new
301
+			expect(obj.states).to eq({
302
+											 critical: { foo: nil },
303
+											 error:    { foo: nil },
304
+											 good:     { foo: nil },
305
+											 great:    { foo: nil } })
306
+		end
307
+
211 308
 		it 'must return empty if no check nor child' do
212 309
 			match_states empty
213 310
 		end
214 311
 
215 312
 		it 'must return personal status if no child' do
216
-			match_states childless, critical: %i(foo), error: %i(bar)
313
+			match_states childless, critical: { foo: true }, error: { bar: true }, warning: { baz: false }
217 314
 		end
218 315
 
219 316
 		it 'must return personal and children statuses' do
220
-			match_states parent, critical: %i(foo), error: %i(bar)
317
+			match_states parent, critical: { foo: true }, error: { bar: true}
221 318
 		end
222 319
 
223 320
 		it 'must return remove duplicated status' do
224
-			match_states duplicated, critical: %i(foo)
321
+			match_states duplicated, critical: { foo: true }, error: { foo: true }
225 322
 		end
226 323
 	end
227 324
 
@@ -230,7 +327,7 @@ describe CryptCheck::State do
230 327
 			empty = Class.new do
231 328
 				include ::CryptCheck::State
232 329
 
233
-				def checks
330
+				def available_checks
234 331
 					[]
235 332
 				end
236 333
 			end.new
@@ -241,8 +338,8 @@ describe CryptCheck::State do
241 338
 			empty = Class.new do
242 339
 				include ::CryptCheck::State
243 340
 
244
-				def checks
245
-					[[:foo, -> (_) { :critical }]]
341
+				def available_checks
342
+					[[:foo, :critical, -> (_) { true }]]
246 343
 				end
247 344
 			end.new
248 345
 			expect(empty.status).to be :critical
@@ -252,9 +349,9 @@ describe CryptCheck::State do
252 349
 			empty = Class.new do
253 350
 				include ::CryptCheck::State
254 351
 
255
-				def checks
256
-					[[:foo, -> (_) { :critical }],
257
-					 [:bar, -> (_) { :error }]]
352
+				def available_checks
353
+					[[:foo, :critical, -> (_) { true }],
354
+					 [:bar, :error, -> (_) { true }]]
258 355
 				end
259 356
 			end.new
260 357
 			expect(empty.status).to be :critical

Loading…
Cancel
Save