mihari 5.5.0 → 5.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/docs/analyzers/binaryedge.md +1 -1
  3. data/docs/analyzers/censys.md +1 -1
  4. data/docs/analyzers/circl.md +1 -1
  5. data/docs/analyzers/crtsh.md +1 -1
  6. data/docs/analyzers/dnstwister.md +1 -1
  7. data/docs/analyzers/greynoise.md +1 -1
  8. data/docs/analyzers/hunterhow.md +1 -1
  9. data/docs/analyzers/index.md +29 -15
  10. data/docs/analyzers/onyphe.md +1 -1
  11. data/docs/analyzers/otx.md +2 -2
  12. data/docs/analyzers/passivetotal.md +6 -2
  13. data/docs/analyzers/pulsedive.md +2 -2
  14. data/docs/analyzers/securitytrails.md +6 -2
  15. data/docs/analyzers/shodan.md +1 -1
  16. data/docs/analyzers/urlscan.md +3 -3
  17. data/docs/analyzers/virustotal.md +6 -2
  18. data/docs/analyzers/virustotal_intelligence.md +8 -4
  19. data/docs/analyzers/zoomeye.md +5 -0
  20. data/docs/emitters/hive.md +1 -1
  21. data/docs/emitters/slack.md +0 -5
  22. data/docs/enrichers/google_public_dns.md +1 -1
  23. data/docs/enrichers/ipinfo.md +2 -2
  24. data/docs/enrichers/shodan.md +4 -4
  25. data/docs/enrichers/whois.md +1 -1
  26. data/docs/rule.md +1 -4
  27. data/docs/usage.md +5 -2
  28. data/frontend/package-lock.json +3 -3
  29. data/frontend/src/components/ErrorMessage.vue +0 -1
  30. data/frontend/src/components/alert/Alerts.vue +0 -1
  31. data/frontend/src/components/alert/AlertsWithPagination.vue +0 -1
  32. data/frontend/src/components/alert/AlertsWrapper.vue +0 -6
  33. data/frontend/src/components/alert/Form.vue +1 -3
  34. data/frontend/src/components/artifact/Artifact.vue +0 -17
  35. data/frontend/src/components/artifact/ArtifactWrapper.vue +0 -2
  36. data/frontend/src/components/artifact/WhoisRecord.vue +0 -3
  37. data/frontend/src/components/config/ConfigsWrapper.vue +0 -2
  38. data/frontend/src/components/rule/EditRule.vue +0 -3
  39. data/frontend/src/components/rule/EditRuleWrapper.vue +0 -2
  40. data/frontend/src/components/rule/Form.vue +1 -3
  41. data/frontend/src/components/rule/NewRule.vue +0 -3
  42. data/frontend/src/components/rule/Rule.vue +1 -7
  43. data/frontend/src/components/rule/RuleWrapper.vue +0 -2
  44. data/frontend/src/components/rule/RulesWrapper.vue +0 -6
  45. data/frontend/src/swagger.yaml +254 -254
  46. data/lib/mihari/analyzers/base.rb +4 -41
  47. data/lib/mihari/analyzers/circl.rb +1 -1
  48. data/lib/mihari/analyzers/crtsh.rb +1 -1
  49. data/lib/mihari/analyzers/dnstwister.rb +1 -1
  50. data/lib/mihari/analyzers/otx.rb +1 -1
  51. data/lib/mihari/analyzers/passivetotal.rb +10 -1
  52. data/lib/mihari/analyzers/pulsedive.rb +2 -2
  53. data/lib/mihari/analyzers/rule.rb +24 -59
  54. data/lib/mihari/analyzers/securitytrails.rb +10 -1
  55. data/lib/mihari/analyzers/virustotal.rb +11 -2
  56. data/lib/mihari/analyzers/virustotal_intelligence.rb +16 -0
  57. data/lib/mihari/analyzers/zoomeye.rb +2 -2
  58. data/lib/mihari/base.rb +69 -0
  59. data/lib/mihari/cli/main.rb +36 -0
  60. data/lib/mihari/clients/base.rb +2 -2
  61. data/lib/mihari/clients/binaryedge.rb +3 -5
  62. data/lib/mihari/clients/censys.rb +3 -3
  63. data/lib/mihari/clients/circl.rb +5 -4
  64. data/lib/mihari/clients/crtsh.rb +3 -2
  65. data/lib/mihari/clients/dnstwister.rb +3 -2
  66. data/lib/mihari/clients/greynoise.rb +2 -2
  67. data/lib/mihari/clients/hunterhow.rb +2 -2
  68. data/lib/mihari/clients/misp.rb +1 -1
  69. data/lib/mihari/clients/onyphe.rb +2 -2
  70. data/lib/mihari/clients/otx.rb +4 -3
  71. data/lib/mihari/clients/passivetotal.rb +5 -4
  72. data/lib/mihari/clients/publsedive.rb +4 -3
  73. data/lib/mihari/clients/securitytrails.rb +5 -3
  74. data/lib/mihari/clients/shodan.rb +2 -2
  75. data/lib/mihari/clients/the_hive.rb +1 -1
  76. data/lib/mihari/clients/urlscan.rb +4 -4
  77. data/lib/mihari/clients/virustotal.rb +2 -2
  78. data/lib/mihari/clients/zoomeye.rb +2 -2
  79. data/lib/mihari/commands/alert.rb +6 -33
  80. data/lib/mihari/commands/rule.rb +7 -12
  81. data/lib/mihari/commands/search.rb +10 -38
  82. data/lib/mihari/constants.rb +3 -3
  83. data/lib/mihari/emitters/base.rb +3 -33
  84. data/lib/mihari/emitters/database.rb +1 -1
  85. data/lib/mihari/enrichers/base.rb +2 -33
  86. data/lib/mihari/enrichers/google_public_dns.rb +9 -0
  87. data/lib/mihari/schemas/analyzer.rb +24 -24
  88. data/lib/mihari/schemas/emitter.rb +6 -13
  89. data/lib/mihari/schemas/enricher.rb +4 -11
  90. data/lib/mihari/schemas/options.rb +27 -0
  91. data/lib/mihari/schemas/rule.rb +2 -2
  92. data/lib/mihari/services/alert_runner.rb +1 -1
  93. data/lib/mihari/services/rule_runner.rb +1 -11
  94. data/lib/mihari/types.rb +1 -14
  95. data/lib/mihari/version.rb +1 -1
  96. data/lib/mihari/web/public/assets/{index-33165282.css → index-56fc2187.css} +1 -1
  97. data/lib/mihari/web/public/assets/{index-b5d817a3.js → index-9cc489e6.js} +2 -2
  98. data/lib/mihari/web/public/index.html +2 -2
  99. data/lib/mihari.rb +67 -37
  100. data/mihari.gemspec +1 -0
  101. data/mkdocs.yml +0 -3
  102. metadata +20 -4
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Mihari
4
4
  module Analyzers
5
- class Base
5
+ class Base < Mihari::Base
6
6
  include Dry::Monads[:result, :try]
7
7
 
8
8
  include Mixins::Configurable
@@ -11,37 +11,14 @@ module Mihari
11
11
  # @return [String]
12
12
  attr_reader :query
13
13
 
14
- # @return [Hash]
15
- attr_reader :options
16
-
17
14
  #
18
15
  # @param [String] query
19
16
  # @param [Hash, nil] options
20
17
  #
21
18
  def initialize(query, options: nil)
22
- @query = query
23
- @options = options || {}
24
- end
25
-
26
- #
27
- # @return [Integer]
28
- #
29
- def retry_interval
30
- options[:retry_interval] || Mihari.config.retry_interval
31
- end
32
-
33
- #
34
- # @return [Boolean]
35
- #
36
- def retry_exponential_backoff
37
- options[:retry_exponential_backoff] || Mihari.config.retry_exponential_backoff
38
- end
19
+ super(options: options)
39
20
 
40
- #
41
- # @return [Integer]
42
- #
43
- def retry_times
44
- options[:retry_times] || Mihari.config.retry_times
21
+ @query = query
45
22
  end
46
23
 
47
24
  #
@@ -68,13 +45,6 @@ module Mihari
68
45
  Mihari.config.ignore_error
69
46
  end
70
47
 
71
- #
72
- # @return [Integer, nil]
73
- #
74
- def timeout
75
- options[:timeout]
76
- end
77
-
78
48
  # @return [Array<String>, Array<Mihari::Artifact>]
79
49
  def artifacts
80
50
  raise NotImplementedError, "You must implement #{self.class}##{__method__}"
@@ -93,7 +63,7 @@ module Mihari
93
63
  # No need to set data_type manually
94
64
  # It is set automatically in #initialize
95
65
  artifact = artifact.is_a?(Artifact) ? artifact : Artifact.new(data: artifact)
96
- artifact.source = source
66
+ artifact.source = self.class.class_key
97
67
  artifact
98
68
  end.select(&:valid?).uniq(&:data)
99
69
  end
@@ -106,13 +76,6 @@ module Mihari
106
76
  Try[StandardError] { normalized_artifacts }.to_result
107
77
  end
108
78
 
109
- # @return [String]
110
- def class_name
111
- self.class.to_s.split("::").last
112
- end
113
-
114
- alias_method :source, :class_name
115
-
116
79
  class << self
117
80
  #
118
81
  # Initialize an analyzer by query params
@@ -51,7 +51,7 @@ module Mihari
51
51
  private
52
52
 
53
53
  def client
54
- @client ||= Clients::CIRCL.new(username: username, password: password)
54
+ @client ||= Clients::CIRCL.new(username: username, password: password, timeout: timeout)
55
55
  end
56
56
 
57
57
  def username?
@@ -28,7 +28,7 @@ module Mihari
28
28
  # @return [Mihari::Clients::Crtsh]
29
29
  #
30
30
  def client
31
- @client ||= Mihari::Clients::Crtsh.new
31
+ @client ||= Mihari::Clients::Crtsh.new(timeout: timeout)
32
32
  end
33
33
  end
34
34
  end
@@ -39,7 +39,7 @@ module Mihari
39
39
  end
40
40
 
41
41
  def client
42
- @client ||= Clients::DNSTwister.new
42
+ @client ||= Clients::DNSTwister.new(timeout: timeout)
43
43
  end
44
44
 
45
45
  #
@@ -42,7 +42,7 @@ module Mihari
42
42
  private
43
43
 
44
44
  def client
45
- @client ||= Mihari::Clients::OTX.new(api_key: api_key)
45
+ @client ||= Mihari::Clients::OTX.new(api_key: api_key, timeout: timeout)
46
46
  end
47
47
 
48
48
  #
@@ -50,10 +50,19 @@ module Mihari
50
50
  %w[passivetotal_username passivetotal_api_key]
51
51
  end
52
52
 
53
+ class << self
54
+ #
55
+ # @return [Array<String>, nil]
56
+ #
57
+ def key_aliases
58
+ ["pt"]
59
+ end
60
+ end
61
+
53
62
  private
54
63
 
55
64
  def client
56
- @client ||= Clients::PassiveTotal.new(username: username, api_key: api_key)
65
+ @client ||= Clients::PassiveTotal.new(username: username, api_key: api_key, timeout: timeout)
57
66
  end
58
67
 
59
68
  #
@@ -35,7 +35,7 @@ module Mihari
35
35
  nil
36
36
  else
37
37
  data = property["value"]
38
- Artifact.new(data: data, source: source, metadata: property)
38
+ Artifact.new(data: data, metadata: property)
39
39
  end
40
40
  end
41
41
  end
@@ -47,7 +47,7 @@ module Mihari
47
47
  private
48
48
 
49
49
  def client
50
- @client ||= Clients::PulseDive.new(api_key: api_key)
50
+ @client ||= Clients::PulseDive.new(api_key: api_key, timeout: timeout)
51
51
  end
52
52
 
53
53
  #
@@ -2,46 +2,6 @@
2
2
 
3
3
  module Mihari
4
4
  module Analyzers
5
- ANALYZER_TO_CLASS = {
6
- "binaryedge" => BinaryEdge,
7
- "censys" => Censys,
8
- "circl" => CIRCL,
9
- "crtsh" => Crtsh,
10
- "dnstwister" => DNSTwister,
11
- "feed" => Feed,
12
- "greynoise" => GreyNoise,
13
- "hunterhow" => HunterHow,
14
- "onyphe" => Onyphe,
15
- "otx" => OTX,
16
- "passivetotal" => PassiveTotal,
17
- "pt" => PassiveTotal,
18
- "pulsedive" => Pulsedive,
19
- "securitytrails" => SecurityTrails,
20
- "shodan" => Shodan,
21
- "st" => SecurityTrails,
22
- "urlscan" => Urlscan,
23
- "virustotal_intelligence" => VirusTotalIntelligence,
24
- "virustotal" => VirusTotal,
25
- "vt_intel" => VirusTotalIntelligence,
26
- "vt" => VirusTotal,
27
- "zoomeye" => ZoomEye
28
- }.freeze
29
-
30
- EMITTER_TO_CLASS = {
31
- "database" => Emitters::Database,
32
- "misp" => Emitters::MISP,
33
- "slack" => Emitters::Slack,
34
- "the_hive" => Emitters::TheHive,
35
- "webhook" => Emitters::Webhook
36
- }.freeze
37
-
38
- ENRICHER_TO_CLASS = {
39
- "whois" => Enrichers::Whois,
40
- "ipinfo" => Enrichers::IPInfo,
41
- "shodan" => Enrichers::Shodan,
42
- "google_public_dns" => Enrichers::GooglePublicDNS
43
- }.freeze
44
-
45
5
  class Rule
46
6
  include Mixins::FalsePositive
47
7
 
@@ -126,8 +86,14 @@ module Mihari
126
86
  def bulk_emit
127
87
  return [] if enriched_artifacts.empty?
128
88
 
129
- Parallel.map(valid_emitters) do |emitter|
130
- result = emitter.result
89
+ # NOTE: separate parallel execution and logging
90
+ # because the logger does not work along with Parallel
91
+ results = Parallel.map(valid_emitters) do |emitter|
92
+ emitter.result
93
+ end
94
+
95
+ results.zip(valid_emitters).map do |result_and_emitter|
96
+ result, emitter = result_and_emitter
131
97
 
132
98
  Mihari.logger.info "Emission by #{emitter.class} is failed: #{result.failure}" if result.failure?
133
99
  Mihari.logger.info "Emission by #{emitter.class} is succeeded" if result.success?
@@ -164,15 +130,14 @@ module Mihari
164
130
  #
165
131
  # Get analyzer class
166
132
  #
167
- # @param [String] analyzer_name
133
+ # @param [String] key
168
134
  #
169
135
  # @return [Class<Mihari::Analyzers::Base>] analyzer class
170
136
  #
171
- def get_analyzer_class(analyzer_name)
172
- analyzer = ANALYZER_TO_CLASS[analyzer_name]
173
- return analyzer if analyzer
137
+ def get_analyzer_class(key)
138
+ raise ArgumentError, "#{key} is not supported" unless Mihari.analyzer_to_class.key?(key)
174
139
 
175
- raise ArgumentError, "#{analyzer_name} is not supported"
140
+ Mihari.analyzer_to_class[key]
176
141
  end
177
142
 
178
143
  #
@@ -189,15 +154,14 @@ module Mihari
189
154
  #
190
155
  # Get emitter class
191
156
  #
192
- # @param [String] emitter_name
157
+ # @param [String] key
193
158
  #
194
159
  # @return [Class<Mihari::Emitters::Base>] emitter class
195
160
  #
196
- def get_emitter_class(emitter_name)
197
- emitter = EMITTER_TO_CLASS[emitter_name]
198
- return emitter if emitter
161
+ def get_emitter_class(key)
162
+ raise ArgumentError, "#{key} is not supported" unless Mihari.emitter_to_class.key?(key)
199
163
 
200
- raise ArgumentError, "#{emitter_name} is not supported"
164
+ Mihari.emitter_to_class[key]
201
165
  end
202
166
 
203
167
  #
@@ -219,21 +183,20 @@ module Mihari
219
183
  # @return [Array<Mihari::Emitters::Base>]
220
184
  #
221
185
  def valid_emitters
222
- emitters.select(&:valid?)
186
+ @valid_emitters ||= emitters.select(&:valid?)
223
187
  end
224
188
 
225
189
  #
226
190
  # Get enricher class
227
191
  #
228
- # @param [String] enricher_name
192
+ # @param [String] key
229
193
  #
230
194
  # @return [Class<Mihari::Enrichers::Base>] enricher class
231
195
  #
232
- def get_enricher_class(enricher_name)
233
- enricher = ENRICHER_TO_CLASS[enricher_name]
234
- return enricher if enricher
196
+ def get_enricher_class(key)
197
+ raise ArgumentError, "#{key} is not supported" unless Mihari.enricher_to_class.key?(key)
235
198
 
236
- raise ArgumentError, "#{enricher_name} is not supported"
199
+ Mihari.enricher_to_class[key]
237
200
  end
238
201
 
239
202
  #
@@ -258,7 +221,9 @@ module Mihari
258
221
  analyzers.map do |analyzer|
259
222
  next if analyzer.configured?
260
223
 
261
- message = "#{analyzer.source} is not configured correctly. #{analyzer.configuration_keys.join(", ")} is/are missing."
224
+ joined = analyzer.configuration_keys.join(", ")
225
+ be = (analyzer.configuration_keys.length > 1) ? "are" : "is"
226
+ message = "#{analyzer.class.class_key} is not configured correctly. #{joined} #{be} missing."
262
227
  raise ConfigurationError, message
263
228
  end
264
229
  end
@@ -44,10 +44,19 @@ module Mihari
44
44
  %w[securitytrails_api_key]
45
45
  end
46
46
 
47
+ class << self
48
+ #
49
+ # @return [Array<String>, nil]
50
+ #
51
+ def key_aliases
52
+ ["st"]
53
+ end
54
+ end
55
+
47
56
  private
48
57
 
49
58
  def client
50
- @client ||= Clients::SecurityTrails.new(api_key: api_key)
59
+ @client ||= Clients::SecurityTrails.new(api_key: api_key, timeout: timeout)
51
60
  end
52
61
 
53
62
  #
@@ -39,6 +39,15 @@ module Mihari
39
39
  %w[virustotal_api_key]
40
40
  end
41
41
 
42
+ class << self
43
+ #
44
+ # @return [Array<String>, nil]
45
+ #
46
+ def key_aliases
47
+ ["vt"]
48
+ end
49
+ end
50
+
42
51
  private
43
52
 
44
53
  def client
@@ -65,7 +74,7 @@ module Mihari
65
74
  data = res["data"] || []
66
75
  data.filter_map do |item|
67
76
  data = item.dig("attributes", "ip_address")
68
- data.nil? ? nil : Artifact.new(data: data, source: source, metadata: item)
77
+ data.nil? ? nil : Artifact.new(data: data, metadata: item)
69
78
  end
70
79
  end
71
80
 
@@ -80,7 +89,7 @@ module Mihari
80
89
  data = res["data"] || []
81
90
  data.filter_map do |item|
82
91
  data = item.dig("attributes", "host_name")
83
- Artifact.new(data: data, source: source, metadata: item)
92
+ Artifact.new(data: data, metadata: item)
84
93
  end.uniq
85
94
  end
86
95
  end
@@ -25,6 +25,22 @@ module Mihari
25
25
  %w[virustotal_api_key]
26
26
  end
27
27
 
28
+ class << self
29
+ #
30
+ # @return [String]
31
+ #
32
+ def class_key
33
+ "virustotal_intelligence"
34
+ end
35
+
36
+ #
37
+ # @return [Array<String>, nil]
38
+ #
39
+ def class_key_aliases
40
+ ["vt_intel"]
41
+ end
42
+ end
43
+
28
44
  private
29
45
 
30
46
  #
@@ -73,9 +73,9 @@ module Mihari
73
73
  data = match["ip"]
74
74
 
75
75
  if data.is_a?(Array)
76
- data.map { |d| Artifact.new(data: d, source: source, metadata: match) }
76
+ data.map { |d| Artifact.new(data: d, metadata: match) }
77
77
  else
78
- Artifact.new(data: data, source: source, metadata: match)
78
+ Artifact.new(data: data, metadata: match)
79
79
  end
80
80
  end.flatten
81
81
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mihari
4
+ #
5
+ # Base class for Analyzer, Emitter and Enricher
6
+ #
7
+ class Base
8
+ # @return [Hash]
9
+ attr_reader :options
10
+
11
+ #
12
+ # @param [Hash, nil] options
13
+ #
14
+ def initialize(*_args, options: nil, **_kwargs)
15
+ @options = options || {}
16
+ end
17
+
18
+ #
19
+ # @return [Integer]
20
+ #
21
+ def retry_interval
22
+ options[:retry_interval] || Mihari.config.retry_interval
23
+ end
24
+
25
+ #
26
+ # @return [Boolean]
27
+ #
28
+ def retry_exponential_backoff
29
+ options[:retry_exponential_backoff] || Mihari.config.retry_exponential_backoff
30
+ end
31
+
32
+ #
33
+ # @return [Integer]
34
+ #
35
+ def retry_times
36
+ options[:retry_times] || Mihari.config.retry_times
37
+ end
38
+
39
+ #
40
+ # @return [Integer, nil]
41
+ #
42
+ def timeout
43
+ options[:timeout]
44
+ end
45
+
46
+ class << self
47
+ #
48
+ # @return [String]
49
+ #
50
+ def class_key
51
+ to_s.split("::").last
52
+ end
53
+
54
+ #
55
+ # @return [Array<String>, nil]
56
+ #
57
+ def class_key_aliases
58
+ nil
59
+ end
60
+
61
+ #
62
+ # @return [Array<String>]
63
+ #
64
+ def class_keys
65
+ ([class_key] + [class_key_aliases]).flatten.compact
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "thor"
4
+ require "thor/hollaback"
4
5
 
5
6
  # Commands
6
7
  require "mihari/commands/alert"
@@ -19,10 +20,45 @@ require "mihari/cli/rule"
19
20
  module Mihari
20
21
  module CLI
21
22
  class Main < Base
23
+ class_option :debug, desc: "Sets up debug mode", aliases: ["-d"], type: :boolean
24
+ class_around :safe_execute
25
+
22
26
  include Mihari::Commands::Search
23
27
  include Mihari::Commands::Version
24
28
  include Mihari::Commands::Web
25
29
 
30
+ no_commands do
31
+ def unwrap_error(err)
32
+ return err unless err.is_a?(Dry::Monads::UnwrapError)
33
+
34
+ # NOTE: UnwrapError's receiver can be either of:
35
+ # - Dry::Monads::Try::Error
36
+ # - Dry::Monads::Result::Failure
37
+ receiver = err.receiver
38
+ return receiver.exception if receiver.is_a?(Dry::Monads::Try::Error)
39
+
40
+ receiver.failure
41
+ end
42
+
43
+ def safe_execute
44
+ yield
45
+ rescue StandardError => e
46
+ err = unwrap_error(e)
47
+
48
+ raise err if options["debug"]
49
+
50
+ case err
51
+ when ValidationError
52
+ warn JSON.pretty_generate(err.errors.to_h)
53
+ when StandardError
54
+ Sentry.capture_exception(err) if Sentry.initialized?
55
+ warn err
56
+ end
57
+
58
+ exit 1
59
+ end
60
+ end
61
+
26
62
  desc "db", "Sub commands for DB"
27
63
  subcommand "db", Database
28
64
 
@@ -18,10 +18,10 @@ module Mihari
18
18
  #
19
19
  # @param [String] base_url
20
20
  # @param [Hash] headers
21
- # @param [Integer] interval
21
+ # @param [Integer] pagination_interval
22
22
  # @param [Integer, nil] timeout
23
23
  #
24
- def initialize(base_url, headers: {}, pagination_interval: 0, timeout: nil)
24
+ def initialize(base_url, headers: {}, pagination_interval: Mihari.config.pagination_interval, timeout: nil)
25
25
  @base_url = base_url
26
26
  @headers = headers || {}
27
27
  @pagination_interval = pagination_interval
@@ -7,21 +7,19 @@ module Mihari
7
7
  # @param [String] base_url
8
8
  # @param [String, nil] api_key
9
9
  # @param [Hash] headers
10
- # @param [Integer] pagnation_interval
11
10
  # @param [Integer, nil] timeout
11
+ # @param [Integer] pagination_interval
12
12
  #
13
13
  def initialize(
14
14
  base_url = "https://api.binaryedge.io/v2",
15
15
  api_key:,
16
16
  headers: {},
17
- pagination_interval: 0,
17
+ pagination_interval: Mihari.config.pagination_interval,
18
18
  timeout: nil
19
19
  )
20
- raise(ArgumentError, "'api_key' argument is required") unless api_key
21
-
22
20
  headers["x-key"] = api_key
23
21
 
24
- super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
22
+ super(base_url, headers: headers, timeout: timeout, pagination_interval: pagination_interval)
25
23
  end
26
24
 
27
25
  #
@@ -18,11 +18,11 @@ module Mihari
18
18
  id:,
19
19
  secret:,
20
20
  headers: {},
21
- pagination_interval: 0,
21
+ pagination_interval: Mihari.config.pagination_interval,
22
22
  timeout: nil
23
23
  )
24
- raise(ArgumentError, "'id' argument is required") if id.nil?
25
- raise(ArgumentError, "'secret' argument is required") if secret.nil?
24
+ raise(ArgumentError, "id is required") if id.nil?
25
+ raise(ArgumentError, "secret is required") if secret.nil?
26
26
 
27
27
  headers["authorization"] = "Basic #{Base64.strict_encode64("#{id}:#{secret}")}"
28
28
 
@@ -10,14 +10,15 @@ module Mihari
10
10
  # @param [String, nil] username
11
11
  # @param [String, nil] password
12
12
  # @param [Hash] headers
13
+ # @param [Integer, nil] timeout
13
14
  #
14
- def initialize(base_url = "https://www.circl.lu", username:, password:, headers: {})
15
- raise(ArgumentError, "'username' argument is required") if username.nil?
16
- raise(ArgumentError, "'password' argument is required") if password.nil?
15
+ def initialize(base_url = "https://www.circl.lu", username:, password:, headers: {}, timeout: nil)
16
+ raise(ArgumentError, "username is required") if username.nil?
17
+ raise(ArgumentError, "password is required") if password.nil?
17
18
 
18
19
  headers["authorization"] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
19
20
 
20
- super(base_url, headers: headers)
21
+ super(base_url, headers: headers, timeout: timeout)
21
22
  end
22
23
 
23
24
  #
@@ -6,9 +6,10 @@ module Mihari
6
6
  #
7
7
  # @param [String] base_url
8
8
  # @param [Hash] headers
9
+ # @param [Integer, nil] timeout
9
10
  #
10
- def initialize(base_url = "https://crt.sh", headers: {})
11
- super(base_url, headers: headers)
11
+ def initialize(base_url = "https://crt.sh", headers: {}, timeout: nil)
12
+ super(base_url, headers: headers, timeout: timeout)
12
13
  end
13
14
 
14
15
  #
@@ -6,9 +6,10 @@ module Mihari
6
6
  #
7
7
  # @param [String] base_url
8
8
  # @param [Hash] headers
9
+ # @param [Integer, nil] timeout
9
10
  #
10
- def initialize(base_url = "https://dnstwister.report", headers: {})
11
- super(base_url, headers: headers)
11
+ def initialize(base_url = "https://dnstwister.report", headers: {}, timeout: nil)
12
+ super(base_url, headers: headers, timeout: timeout)
12
13
  end
13
14
 
14
15
  #
@@ -16,10 +16,10 @@ module Mihari
16
16
  base_url = "https://api.greynoise.io",
17
17
  api_key:,
18
18
  headers: {},
19
- pagination_interval: 0,
19
+ pagination_interval: Mihari.config.pagination_interval,
20
20
  timeout: nil
21
21
  )
22
- raise(ArgumentError, "'api_key' argument is required") unless api_key
22
+ raise(ArgumentError, "api_key is required") unless api_key
23
23
 
24
24
  headers["key"] = api_key
25
25
  super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
@@ -21,10 +21,10 @@ module Mihari
21
21
  base_url = "https://api.hunter.how/",
22
22
  api_key:,
23
23
  headers: {},
24
- pagination_interval: 0,
24
+ pagination_interval: Mihari.config.pagination_interval,
25
25
  timeout: nil
26
26
  )
27
- raise(ArgumentError, "'api_key' argument is required") unless api_key
27
+ raise(ArgumentError, "api_key is required") unless api_key
28
28
 
29
29
  super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
30
30
 
@@ -10,7 +10,7 @@ module Mihari
10
10
  # @param [Integer, nil] timeout
11
11
  #
12
12
  def initialize(base_url, api_key:, headers: {}, timeout: nil)
13
- raise(ArgumentError, "'api_key' argument is required") unless api_key
13
+ raise(ArgumentError, "api_key is required") unless api_key
14
14
 
15
15
  headers["authorization"] = api_key
16
16
  headers["accept"] = "application/json"
@@ -19,10 +19,10 @@ module Mihari
19
19
  base_url = "https://www.onyphe.io",
20
20
  api_key:,
21
21
  headers: {},
22
- pagination_interval: 0,
22
+ pagination_interval: Mihari.config.pagination_interval,
23
23
  timeout: nil
24
24
  )
25
- raise(ArgumentError, "'api_key' argument is required") if api_key.nil?
25
+ raise(ArgumentError, "api_key is required") if api_key.nil?
26
26
 
27
27
  super(base_url, headers: headers, pagination_interval: pagination_interval, timeout: timeout)
28
28