Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. module CryptCheck
  2. module State
  3. def states
  4. # Remove duplicated test for each level
  5. @states ||= State.empty.merge(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)
  20. end
  21. def status
  22. @status ||= State.status self.checks.select { |c| c.last == true }.collect { |c| c[1] }
  23. end
  24. BADS = %i(critical error warning).freeze
  25. GOODS = %i(good great best).freeze
  26. LEVELS = (BADS + GOODS).freeze
  27. def self.good?(level)
  28. GOODS.include? level
  29. end
  30. def self.bad?(level)
  31. BADS.include? level
  32. end
  33. def self.good_or_bad(level)
  34. if self.good?(level)
  35. :good
  36. else
  37. :bad
  38. end
  39. end
  40. def self.state(states, level)
  41. state =states[level].values.uniq
  42. case State.good_or_bad(level)
  43. when :bad
  44. if state.include? true
  45. true
  46. else
  47. false
  48. end
  49. when :good
  50. if state.include? false
  51. if state.include? true
  52. :some
  53. else
  54. false
  55. end
  56. else
  57. :all
  58. end
  59. end
  60. end
  61. extend Enumerable
  62. def self.each(&block)
  63. LEVELS.each &block
  64. end
  65. def self.empty
  66. self.collect { |s| [s, {}] }.to_h
  67. end
  68. def self.status(states)
  69. states = self.convert states
  70. self.min LEVELS, states
  71. end
  72. class << self
  73. alias_method :'[]', :status
  74. end
  75. def self.problem(states)
  76. states = self.convert states
  77. self.min BADS, states
  78. end
  79. def self.sort(states)
  80. states.sort { |a, b| self.compare a, b }
  81. end
  82. def self.compare(a, b)
  83. a = LEVELS.find_index(a.status) || (LEVELS.size - 1) / 2.0
  84. b = LEVELS.find_index(b.status) || (LEVELS.size - 1) / 2.0
  85. b <=> a
  86. end
  87. protected
  88. def checks
  89. @checks ||= self.available_checks.collect { |c| perform_check c }.flatten(1) + children.collect(&:checks).flatten(1)
  90. end
  91. private
  92. def self.convert(status)
  93. status = [status] unless status.respond_to? :first
  94. first = status.first
  95. status = status.collect &:status if first.respond_to? :status
  96. status
  97. end
  98. def self.min(levels, states)
  99. return nil if states.empty?
  100. (levels & states).first
  101. end
  102. def self.max(levels, states)
  103. return nil if states.empty?
  104. (levels & states).last
  105. end
  106. def self.merge(*states)
  107. State.collect do |s|
  108. state = states.collect { |ss| ss.fetch s, [] }
  109. .inject(&:+).uniq
  110. [s, state]
  111. end.to_h
  112. end
  113. def children
  114. []
  115. end
  116. def perform_check(check)
  117. name, levels, check = check
  118. result = check.call self
  119. case levels
  120. when Symbol # Expected result is true/false/nil
  121. return [[name, levels, result]]
  122. else # Expected result is the best/worst case
  123. # N/A, so return all levels as N/A
  124. return levels.collect { |l| [name, l, nil] } if result.nil?
  125. checks = []
  126. if BADS.include? result
  127. checks += (GOODS & levels).collect { |l| [name, l, false] }
  128. index = BADS.index result
  129. checks += (BADS & levels).collect { |l| [name, l, BADS.index(l) >= index] }
  130. else
  131. checks += (BADS & levels).collect { |l| [name, l, false] }
  132. index = GOODS.index result
  133. checks += (GOODS & levels).collect { |l| [name, l, GOODS.index(l) <= index] }
  134. end
  135. return checks
  136. end
  137. end
  138. end
  139. end