mihari 5.7.2 → 6.0.0
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.
- checksums.yaml +4 -4
- data/config.ru +2 -0
- data/lib/mihari/analyzers/dnstwister.rb +2 -4
- data/lib/mihari/analyzers/urlscan.rb +1 -4
- data/lib/mihari/cli/main.rb +2 -12
- data/lib/mihari/commands/database.rb +0 -1
- data/lib/mihari/database.rb +2 -4
- data/lib/mihari/emitters/slack.rb +3 -6
- data/lib/mihari/emitters/the_hive.rb +3 -7
- data/lib/mihari/enrichers/google_public_dns.rb +2 -7
- data/lib/mihari/enrichers/ipinfo.rb +1 -3
- data/lib/mihari/enrichers/shodan.rb +1 -3
- data/lib/mihari/enrichers/whois.rb +0 -4
- data/lib/mihari/mixins/refang.rb +1 -4
- data/lib/mihari/mixins/unwrap_error.rb +27 -0
- data/lib/mihari/models/alert.rb +1 -3
- data/lib/mihari/models/artifact.rb +5 -7
- data/lib/mihari/models/rule.rb +1 -2
- data/lib/mihari/rule.rb +14 -10
- data/lib/mihari/service.rb +2 -0
- data/lib/mihari/services/rule_builder.rb +2 -4
- data/lib/mihari/structs/fofa.rb +2 -0
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/app.rb +3 -1
- data/lib/mihari/web/endpoints/alerts.rb +14 -18
- data/lib/mihari/web/endpoints/artifacts.rb +17 -22
- data/lib/mihari/web/endpoints/configs.rb +0 -1
- data/lib/mihari/web/endpoints/ip_addresses.rb +1 -1
- data/lib/mihari/web/endpoints/rules.rb +27 -32
- data/lib/mihari/web/endpoints/tags.rb +7 -9
- data/lib/mihari/web/middleware/connection_adapter.rb +3 -5
- data/lib/mihari/web/middleware/error_notification_adapter.rb +10 -6
- data/lib/mihari/web/public/assets/{index-ec641cb0.js → index-07cddfcd.js} +3 -3
- data/lib/mihari/web/public/index.html +1 -1
- data/lib/mihari/web/public/redoc-static.html +29 -49
- data/lib/mihari.rb +1 -1
- data/mihari.gemspec +10 -12
- data/requirements.txt +1 -1
- metadata +72 -30
- data/lib/mihari/services/rule_runner.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2846f5154fcdde4cda4f0237c79e047fc498b96b5c21a6152287ac9ab11faac9
|
4
|
+
data.tar.gz: f43b4e20a59b1274b62c5e9768f153429540067882508b34f0c36932cc9cb5ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b54da0da25e57531c1efef94bdc42df715569b9e88842ca330d1d0893f4c20990bb2ded22a001f31816cbd72f00f43473f0254f222a9849308be746576128e3c
|
7
|
+
data.tar.gz: 7167afd356c4f945e66631bb3c6cefc06678961b480511d85939e6ede9eccec9a5f83a948a169be9ee7ba5cc79af918a447b8f01e5280faff3138071e7808beb
|
data/config.ru
CHANGED
@@ -25,9 +25,7 @@ module Mihari
|
|
25
25
|
raise ValueError, "#{query}(type: #{type || "unknown"}) is not supported." unless valid_type?
|
26
26
|
|
27
27
|
domains = client.fuzz(query)
|
28
|
-
Parallel.map(domains)
|
29
|
-
resolvable?(domain) ? domain : nil
|
30
|
-
end.compact
|
28
|
+
Parallel.map(domains) { |domain| resolvable?(domain) ? domain : nil }.compact
|
31
29
|
end
|
32
30
|
|
33
31
|
private
|
@@ -55,7 +53,7 @@ module Mihari
|
|
55
53
|
def resolvable?(domain)
|
56
54
|
Resolv.getaddress domain
|
57
55
|
true
|
58
|
-
rescue Resolv::ResolvError
|
56
|
+
rescue Resolv::ResolvError
|
59
57
|
false
|
60
58
|
end
|
61
59
|
end
|
@@ -34,10 +34,7 @@ module Mihari
|
|
34
34
|
def artifacts
|
35
35
|
# @type [Array<Mihari::Models::Artifact>]
|
36
36
|
artifacts = client.search_with_pagination(query, pagination_limit: pagination_limit).map(&:artifacts).flatten
|
37
|
-
|
38
|
-
artifacts.select do |artifact|
|
39
|
-
allowed_data_types.include? artifact.data_type
|
40
|
-
end
|
37
|
+
artifacts.select { |artifact| allowed_data_types.include? artifact.data_type }
|
41
38
|
end
|
42
39
|
|
43
40
|
def configuration_keys
|
data/lib/mihari/cli/main.rb
CHANGED
@@ -32,19 +32,9 @@ module Mihari
|
|
32
32
|
include Mihari::Commands::Version
|
33
33
|
include Mihari::Commands::Web
|
34
34
|
|
35
|
-
|
36
|
-
def unwrap_error(err)
|
37
|
-
return err unless err.is_a?(Dry::Monads::UnwrapError)
|
38
|
-
|
39
|
-
# NOTE: UnwrapError's receiver can be either of:
|
40
|
-
# - Dry::Monads::Try::Error
|
41
|
-
# - Dry::Monads::Result::Failure
|
42
|
-
receiver = err.receiver
|
43
|
-
return receiver.exception if receiver.is_a?(Dry::Monads::Try::Error)
|
44
|
-
|
45
|
-
receiver.failure
|
46
|
-
end
|
35
|
+
include Mihari::Mixins::UnwrapError
|
47
36
|
|
37
|
+
no_commands do
|
48
38
|
def safe_execute
|
49
39
|
yield
|
50
40
|
rescue StandardError => e
|
data/lib/mihari/database.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Make possible to use upper case acronyms in class names
|
4
|
-
ActiveSupport::Inflector.inflections(:en)
|
5
|
-
inflect.acronym "CPE"
|
6
|
-
end
|
4
|
+
ActiveSupport::Inflector.inflections(:en) { |inflect| inflect.acronym "CPE" }
|
7
5
|
|
8
6
|
def env
|
9
7
|
ENV["APP_ENV"] || ENV["RACK_ENV"]
|
@@ -175,7 +173,7 @@ module Mihari
|
|
175
173
|
Mihari::Database.connect
|
176
174
|
yield
|
177
175
|
rescue ActiveRecord::StatementInvalid
|
178
|
-
Mihari.logger.error("
|
176
|
+
Mihari.logger.error("The DB migration is not yet complete. Please run 'mihari db migrate'.")
|
179
177
|
ensure
|
180
178
|
Mihari::Database.close
|
181
179
|
end
|
@@ -192,9 +192,7 @@ module Mihari
|
|
192
192
|
# @return [Array<Mihari::Emitters::Attachment>]
|
193
193
|
#
|
194
194
|
def attachments
|
195
|
-
artifacts.map
|
196
|
-
Attachment.new(data: artifact.data, data_type: artifact.data_type).to_a
|
197
|
-
end.flatten
|
195
|
+
artifacts.map { |artifact| Attachment.new(data: artifact.data, data_type: artifact.data_type).to_a }.flatten
|
198
196
|
end
|
199
197
|
|
200
198
|
#
|
@@ -205,7 +203,6 @@ module Mihari
|
|
205
203
|
def text
|
206
204
|
tags = rule.tags
|
207
205
|
tags = ["N/A"] if tags.empty?
|
208
|
-
|
209
206
|
[
|
210
207
|
"*#{rule.title}*",
|
211
208
|
"*Desc.*: #{rule.description}",
|
@@ -217,10 +214,10 @@ module Mihari
|
|
217
214
|
# @param [Array<Mihari::Models::Artifact>] artifacts
|
218
215
|
#
|
219
216
|
def call(artifacts)
|
220
|
-
return if artifacts.empty?
|
221
|
-
|
222
217
|
@artifacts = artifacts
|
223
218
|
|
219
|
+
return if artifacts.empty?
|
220
|
+
|
224
221
|
notifier.post(text: text, attachments: attachments, mrkdwn: true)
|
225
222
|
end
|
226
223
|
|
@@ -43,10 +43,10 @@ module Mihari
|
|
43
43
|
# @param [Array<Mihari::Models::Artifact>] artifacts
|
44
44
|
#
|
45
45
|
def call(artifacts)
|
46
|
-
return if artifacts.empty?
|
47
|
-
|
48
46
|
@artifacts = artifacts
|
49
47
|
|
48
|
+
return if artifacts.empty?
|
49
|
+
|
50
50
|
client.alert payload
|
51
51
|
end
|
52
52
|
|
@@ -61,11 +61,7 @@ module Mihari
|
|
61
61
|
@normalized_api_version ||= [].tap do |out|
|
62
62
|
# v4 does not have version prefix in path (/api/)
|
63
63
|
# v5 has version prefix in path (/api/v1/)
|
64
|
-
table = {
|
65
|
-
"" => nil,
|
66
|
-
"v4" => nil,
|
67
|
-
"v5" => "v1"
|
68
|
-
}
|
64
|
+
table = { "" => nil, "v4" => nil, "v5" => "v1" }
|
69
65
|
out << table[api_version.to_s.downcase]
|
70
66
|
end.first
|
71
67
|
end
|
@@ -14,9 +14,7 @@ module Mihari
|
|
14
14
|
# @return [Array<Mihari::Structs::GooglePublicDNS::Response>]
|
15
15
|
#
|
16
16
|
def call(name)
|
17
|
-
%w[A AAAA CNAME TXT NS].filter_map
|
18
|
-
query_by_type(name, resource_type)
|
19
|
-
end
|
17
|
+
%w[A AAAA CNAME TXT NS].filter_map { |resource_type| query_by_type(name, resource_type) }
|
20
18
|
end
|
21
19
|
|
22
20
|
#
|
@@ -31,10 +29,7 @@ module Mihari
|
|
31
29
|
url = "https://dns.google/resolve"
|
32
30
|
params = { name: name, type: resource_type }
|
33
31
|
res = http.get(url, params: params)
|
34
|
-
|
35
|
-
data = JSON.parse(res.body.to_s)
|
36
|
-
|
37
|
-
Structs::GooglePublicDNS::Response.from_dynamic! data
|
32
|
+
Structs::GooglePublicDNS::Response.from_dynamic! JSON.parse(res.body.to_s)
|
38
33
|
rescue HTTPError
|
39
34
|
nil
|
40
35
|
end
|
@@ -33,9 +33,7 @@ module Mihari
|
|
33
33
|
def call(ip)
|
34
34
|
url = "https://ipinfo.io/#{ip}/json"
|
35
35
|
res = http.get(url)
|
36
|
-
|
37
|
-
|
38
|
-
Structs::IPInfo::Response.from_dynamic! data
|
36
|
+
Structs::IPInfo::Response.from_dynamic! JSON.parse(res.body.to_s)
|
39
37
|
end
|
40
38
|
|
41
39
|
private
|
@@ -16,9 +16,7 @@ module Mihari
|
|
16
16
|
def call(ip)
|
17
17
|
url = "https://internetdb.shodan.io/#{ip}"
|
18
18
|
res = http.get(url)
|
19
|
-
|
20
|
-
|
21
|
-
Structs::Shodan::InternetDBResponse.from_dynamic! data
|
19
|
+
Structs::Shodan::InternetDBResponse.from_dynamic! JSON.parse(res.body.to_s)
|
22
20
|
end
|
23
21
|
|
24
22
|
private
|
data/lib/mihari/mixins/refang.rb
CHANGED
@@ -14,10 +14,7 @@ module Mihari
|
|
14
14
|
# @return [String]
|
15
15
|
#
|
16
16
|
def refang(indicator)
|
17
|
-
|
18
|
-
|
19
|
-
# for RSpec & Ruby 2.7
|
20
|
-
indicator
|
17
|
+
indicator.gsub("[.]", ".").gsub("(.)", ".")
|
21
18
|
end
|
22
19
|
end
|
23
20
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mihari
|
4
|
+
module Mixins
|
5
|
+
#
|
6
|
+
# Unwrap error mixins
|
7
|
+
#
|
8
|
+
module UnwrapError
|
9
|
+
def unwrap_error(err)
|
10
|
+
return err unless err.is_a?(Dry::Monads::UnwrapError)
|
11
|
+
|
12
|
+
# NOTE: UnwrapError's receiver can be either of:
|
13
|
+
# - Dry::Monads::Try::Error
|
14
|
+
# - Dry::Monads::Result::Failure
|
15
|
+
receiver = err.receiver
|
16
|
+
case receiver
|
17
|
+
when Dry::Monads::Try::Error
|
18
|
+
receiver.exception
|
19
|
+
when Dry::Monads::Failure
|
20
|
+
receiver.failure
|
21
|
+
else
|
22
|
+
err
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/mihari/models/alert.rb
CHANGED
@@ -30,7 +30,6 @@ module Mihari
|
|
30
30
|
offset = (page - 1) * limit
|
31
31
|
|
32
32
|
relation = build_relation(filter.without_pagination)
|
33
|
-
|
34
33
|
alert_ids = relation.limit(limit).offset(offset).order(id: :desc).pluck(:id).uniq
|
35
34
|
eager_load(:artifacts, :tags).where(id: [alert_ids]).order(id: :desc)
|
36
35
|
end
|
@@ -75,8 +74,7 @@ module Mihari
|
|
75
74
|
def build_relation(filter)
|
76
75
|
artifact_ids = get_artifact_ids_by_filter(filter)
|
77
76
|
|
78
|
-
relation =
|
79
|
-
relation = relation.includes(:artifacts, :tags)
|
77
|
+
relation = includes(:artifacts, :tags)
|
80
78
|
|
81
79
|
relation = relation.where(artifacts: { id: artifact_ids }) unless artifact_ids.empty?
|
82
80
|
relation = relation.where(tags: { name: filter.tag_name }) if filter.tag_name
|
@@ -78,7 +78,7 @@ module Mihari
|
|
78
78
|
end
|
79
79
|
|
80
80
|
#
|
81
|
-
# Enrich
|
81
|
+
# Enrich whois record
|
82
82
|
#
|
83
83
|
# @param [Mihari::Enrichers::Whois] enricher
|
84
84
|
#
|
@@ -89,7 +89,7 @@ module Mihari
|
|
89
89
|
end
|
90
90
|
|
91
91
|
#
|
92
|
-
# Enrich
|
92
|
+
# Enrich DNS records
|
93
93
|
#
|
94
94
|
# @param [Mihari::Enrichers::GooglePublicDNS] enricher
|
95
95
|
#
|
@@ -100,7 +100,7 @@ module Mihari
|
|
100
100
|
end
|
101
101
|
|
102
102
|
#
|
103
|
-
# Enrich
|
103
|
+
# Enrich reverse DNS names
|
104
104
|
#
|
105
105
|
# @param [Mihari::Enrichers::Shodan] enricher
|
106
106
|
#
|
@@ -111,7 +111,7 @@ module Mihari
|
|
111
111
|
end
|
112
112
|
|
113
113
|
#
|
114
|
-
# Enrich
|
114
|
+
# Enrich geolocation
|
115
115
|
#
|
116
116
|
# @param [Mihari::Enrichers::IPInfo] enricher
|
117
117
|
#
|
@@ -192,9 +192,7 @@ module Mihari
|
|
192
192
|
#
|
193
193
|
def enrich_by_enricher(enricher)
|
194
194
|
methods = ENRICH_METHODS_BY_ENRICHER[enricher.class] || []
|
195
|
-
methods.each
|
196
|
-
send(method, enricher) if respond_to?(method)
|
197
|
-
end
|
195
|
+
methods.each { |method| send(method, enricher) if respond_to?(method) }
|
198
196
|
end
|
199
197
|
|
200
198
|
private
|
data/lib/mihari/models/rule.rb
CHANGED
@@ -66,8 +66,7 @@ module Mihari
|
|
66
66
|
# @return [Mihari::Models::Rule]
|
67
67
|
#
|
68
68
|
def build_relation(filter)
|
69
|
-
relation =
|
70
|
-
relation = relation.includes(alerts: :tags)
|
69
|
+
relation = includes(alerts: :tags)
|
71
70
|
|
72
71
|
relation = relation.where(alerts: { tags: { name: filter.tag_name } }) if filter.tag_name
|
73
72
|
|
data/lib/mihari/rule.rb
CHANGED
@@ -113,15 +113,15 @@ module Mihari
|
|
113
113
|
analyzers.flat_map do |analyzer|
|
114
114
|
# @type [Dry::Monads::Result::Success<Array<Mihari::Models::Artifact>>, Dry::Monads::Result::Failure]
|
115
115
|
result = analyzer.result
|
116
|
-
|
117
|
-
|
118
|
-
raise result.failure unless analyzer.ignore_error?
|
119
|
-
else
|
116
|
+
case result
|
117
|
+
when Success
|
120
118
|
artifacts = result.value!
|
121
119
|
artifacts.map do |artifact|
|
122
120
|
artifact.rule_id = id
|
123
121
|
artifact
|
124
122
|
end
|
123
|
+
else
|
124
|
+
raise result.failure unless analyzer.ignore_error?
|
125
125
|
end
|
126
126
|
end.compact
|
127
127
|
end
|
@@ -177,8 +177,14 @@ module Mihari
|
|
177
177
|
results = Parallel.map(emitters) { |emitter| emitter.result enriched_artifacts }
|
178
178
|
results.zip(emitters).map do |result_and_emitter|
|
179
179
|
result, emitter = result_and_emitter
|
180
|
-
|
181
|
-
|
180
|
+
|
181
|
+
case result
|
182
|
+
when Success
|
183
|
+
Mihari.logger.info "Emission by #{emitter.class} succeed"
|
184
|
+
else
|
185
|
+
Mihari.logger.info "Emission by #{emitter.class} failed: #{result.failure}"
|
186
|
+
end
|
187
|
+
|
182
188
|
result.value_or nil
|
183
189
|
end.compact
|
184
190
|
end
|
@@ -289,8 +295,7 @@ module Mihari
|
|
289
295
|
@analyzers ||= queries.map do |query_params|
|
290
296
|
analyzer_name = query_params[:analyzer]
|
291
297
|
klass = get_analyzer_class(analyzer_name)
|
292
|
-
klass.from_query(query_params)
|
293
|
-
end.map do |analyzer|
|
298
|
+
analyzer = klass.from_query(query_params)
|
294
299
|
analyzer.validate_configuration!
|
295
300
|
analyzer
|
296
301
|
end
|
@@ -320,8 +325,7 @@ module Mihari
|
|
320
325
|
%i[emitter options].each { |key| params.delete key }
|
321
326
|
|
322
327
|
klass = get_emitter_class(name)
|
323
|
-
klass.new(rule: self, options: options, **params)
|
324
|
-
end.map do |emitter|
|
328
|
+
emitter = klass.new(rule: self, options: options, **params)
|
325
329
|
emitter.validate_configuration!
|
326
330
|
emitter
|
327
331
|
end
|
data/lib/mihari/service.rb
CHANGED
@@ -20,10 +20,8 @@ module Mihari
|
|
20
20
|
# @return [Hash]
|
21
21
|
#
|
22
22
|
def data
|
23
|
-
|
24
|
-
|
25
|
-
return rule.data
|
26
|
-
end
|
23
|
+
result = Try { Mihari::Models::Rule.find path_or_id }.to_result
|
24
|
+
return result.value! if result.success?
|
27
25
|
|
28
26
|
raise ArgumentError, "#{path_or_id} does not exist" unless Pathname(path_or_id).exist?
|
29
27
|
|
data/lib/mihari/structs/fofa.rb
CHANGED
data/lib/mihari/version.rb
CHANGED
data/lib/mihari/web/app.rb
CHANGED
@@ -39,7 +39,7 @@ module Mihari
|
|
39
39
|
|
40
40
|
def call(env)
|
41
41
|
status, headers, body = API.call(env)
|
42
|
-
return [status, headers, body] unless headers["
|
42
|
+
return [status, headers, body] unless headers["x-cascade"] == "pass"
|
43
43
|
|
44
44
|
# Check if the App wants us to pass the response along to others
|
45
45
|
request_path = env["PATH_INFO"]
|
@@ -64,6 +64,8 @@ module Mihari
|
|
64
64
|
use Middleware::ConnectionAdapter
|
65
65
|
use Middleware::ErrorNotificationAdapter
|
66
66
|
|
67
|
+
use BetterErrors::Middleware if ENV["RACK_ENV"] == "development" && defined?(BetterErrors::Middleware)
|
68
|
+
|
67
69
|
run App.new
|
68
70
|
end.to_app
|
69
71
|
end
|
@@ -77,7 +77,6 @@ module Mihari
|
|
77
77
|
desc "Search alerts", {
|
78
78
|
is_array: true,
|
79
79
|
success: Entities::AlertsWithPagination,
|
80
|
-
failure: [{ code: 404, message: "Not found", model: Entities::Message }],
|
81
80
|
summary: "Search alerts"
|
82
81
|
}
|
83
82
|
params do
|
@@ -103,31 +102,30 @@ module Mihari
|
|
103
102
|
end
|
104
103
|
|
105
104
|
desc "Delete an alert", {
|
106
|
-
success: Entities::Message,
|
107
|
-
failure: [{ code: 404,
|
105
|
+
success: { code: 204, model: Entities::Message },
|
106
|
+
failure: [{ code: 404, model: Entities::Message }],
|
108
107
|
summary: "Delete an alert"
|
109
108
|
}
|
110
109
|
params do
|
111
110
|
requires :id, type: Integer
|
112
111
|
end
|
113
112
|
delete "/:id" do
|
113
|
+
status 204
|
114
|
+
|
114
115
|
id = params["id"].to_i
|
115
116
|
result = AlertDestroyer.result(id)
|
116
|
-
if result.success?
|
117
|
-
status 204
|
118
|
-
return present({ message: "" }, with: Entities::Message)
|
119
|
-
end
|
117
|
+
return present({ message: "" }, with: Entities::Message) if result.success?
|
120
118
|
|
121
|
-
|
122
|
-
case failure
|
119
|
+
case result.failure
|
123
120
|
when ActiveRecord::RecordNotFound
|
124
121
|
error!({ message: "ID:#{id} is not found" }, 404)
|
125
122
|
end
|
126
|
-
raise failure
|
123
|
+
raise result.failure
|
127
124
|
end
|
128
125
|
|
129
126
|
desc "Create an alert", {
|
130
|
-
success: Entities::Alert,
|
127
|
+
success: { code: 201, model: Entities::Alert },
|
128
|
+
failure: [{ code: 404, model: Entities::Message }],
|
131
129
|
summary: "Create an alert"
|
132
130
|
}
|
133
131
|
params do
|
@@ -135,18 +133,16 @@ module Mihari
|
|
135
133
|
requires :artifacts, type: Array, documentation: { type: String, is_array: true, param_type: "body" }
|
136
134
|
end
|
137
135
|
post "/" do
|
136
|
+
status 201
|
137
|
+
|
138
138
|
result = AlertCreator.result(params)
|
139
|
-
if result.success?
|
140
|
-
status 201
|
141
|
-
return present(result.value!, with: Entities::Alert)
|
142
|
-
end
|
139
|
+
return present(result.value!, with: Entities::Alert) if result.success?
|
143
140
|
|
144
|
-
|
145
|
-
case failure
|
141
|
+
case result.failure
|
146
142
|
when ActiveRecord::RecordNotFound
|
147
143
|
error!({ message: "Rule:#{params["ruleId"]} is not found" }, 404)
|
148
144
|
end
|
149
|
-
raise failure
|
145
|
+
raise result.failure
|
150
146
|
end
|
151
147
|
end
|
152
148
|
end
|
@@ -64,7 +64,7 @@ module Mihari
|
|
64
64
|
namespace :artifacts do
|
65
65
|
desc "Get an artifact", {
|
66
66
|
success: Entities::Artifact,
|
67
|
-
failure: [{ code: 404,
|
67
|
+
failure: [{ code: 404, model: Entities::Message }],
|
68
68
|
summary: "Get an artifact"
|
69
69
|
}
|
70
70
|
params do
|
@@ -75,60 +75,55 @@ module Mihari
|
|
75
75
|
result = ArtifactGetter.result(id)
|
76
76
|
return present(result.value!, with: Entities::Artifact) if result.success?
|
77
77
|
|
78
|
-
|
79
|
-
case failure
|
78
|
+
case result.failure
|
80
79
|
when ActiveRecord::RecordNotFound
|
81
80
|
error!({ message: "ID:#{id} is not found" }, 404)
|
82
81
|
end
|
83
|
-
raise failure
|
82
|
+
raise result.failure
|
84
83
|
end
|
85
84
|
|
86
85
|
desc "Enrich an artifact", {
|
87
|
-
success: Entities::Message,
|
88
|
-
failure: [{ code: 404,
|
86
|
+
success: { code: 201, model: Entities::Message },
|
87
|
+
failure: [{ code: 404, model: Entities::Message }],
|
89
88
|
summary: "Enrich an artifact"
|
90
89
|
}
|
91
90
|
params do
|
92
91
|
requires :id, type: Integer
|
93
92
|
end
|
94
93
|
get "/:id/enrich" do
|
94
|
+
status 201
|
95
|
+
|
95
96
|
id = params["id"].to_i
|
96
97
|
result = ArtifactEnricher.result(id)
|
97
|
-
if result.success?
|
98
|
-
status 201
|
99
|
-
return present({ message: "" }, with: Entities::Message)
|
100
|
-
end
|
98
|
+
return present({ message: "#{id} has been enriched" }, with: Entities::Message) if result.success?
|
101
99
|
|
102
|
-
|
103
|
-
case failure
|
100
|
+
case result.failure
|
104
101
|
when ActiveRecord::RecordNotFound
|
105
102
|
error!({ message: "ID:#{id} is not found" }, 404)
|
106
103
|
end
|
107
|
-
raise failure
|
104
|
+
raise result.failure
|
108
105
|
end
|
109
106
|
|
110
107
|
desc "Delete an artifact", {
|
111
|
-
success: Entities::Message,
|
112
|
-
failure: [{ code: 404,
|
108
|
+
success: { code: 204, model: Entities::Message },
|
109
|
+
failure: [{ code: 404, model: Entities::Message }],
|
113
110
|
summary: "Delete an artifact"
|
114
111
|
}
|
115
112
|
params do
|
116
113
|
requires :id, type: Integer
|
117
114
|
end
|
118
115
|
delete "/:id" do
|
116
|
+
status 204
|
117
|
+
|
119
118
|
id = params["id"].to_i
|
120
119
|
result = ArtifactDestroyer.result(id)
|
121
|
-
if result.success?
|
122
|
-
status 204
|
123
|
-
return present({ message: "" }, with: Entities::Message)
|
124
|
-
end
|
120
|
+
return present({ message: "" }, with: Entities::Message) if result.success?
|
125
121
|
|
126
|
-
|
127
|
-
case failure
|
122
|
+
case result.failure
|
128
123
|
when ActiveRecord::RecordNotFound
|
129
124
|
error!({ message: "ID:#{id} is not found" }, 404)
|
130
125
|
end
|
131
|
-
raise failure
|
126
|
+
raise result.failure
|
132
127
|
end
|
133
128
|
end
|
134
129
|
end
|
@@ -21,7 +21,7 @@ module Mihari
|
|
21
21
|
namespace :ip_addresses do
|
22
22
|
desc "Get an IP address", {
|
23
23
|
success: Entities::IPAddress,
|
24
|
-
failure: [{ code: 404,
|
24
|
+
failure: [{ code: 404, model: Entities::Message }],
|
25
25
|
summary: "Get an IP address"
|
26
26
|
}
|
27
27
|
params do
|