mihari 5.7.1 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +4 -12
- data/lib/mihari/clients/base.rb +23 -1
- data/lib/mihari/clients/binaryedge.rb +1 -3
- data/lib/mihari/clients/censys.rb +1 -2
- data/lib/mihari/clients/crtsh.rb +2 -3
- data/lib/mihari/clients/dnstwister.rb +1 -2
- data/lib/mihari/clients/fofa.rb +1 -3
- data/lib/mihari/clients/greynoise.rb +1 -2
- data/lib/mihari/clients/hunterhow.rb +1 -2
- data/lib/mihari/clients/misp.rb +1 -2
- data/lib/mihari/clients/onyphe.rb +1 -2
- data/lib/mihari/clients/otx.rb +2 -14
- data/lib/mihari/clients/passivetotal.rb +3 -16
- data/lib/mihari/clients/publsedive.rb +2 -17
- data/lib/mihari/clients/securitytrails.rb +3 -25
- data/lib/mihari/clients/shodan.rb +1 -2
- data/lib/mihari/clients/the_hive.rb +1 -2
- data/lib/mihari/clients/urlscan.rb +1 -2
- data/lib/mihari/clients/virustotal.rb +3 -17
- data/lib/mihari/clients/zoomeye.rb +9 -19
- data/lib/mihari/commands/alert.rb +11 -11
- data/lib/mihari/commands/database.rb +4 -2
- data/lib/mihari/commands/mixins.rb +11 -0
- data/lib/mihari/commands/search.rb +15 -15
- data/lib/mihari/constants.rb +1 -1
- data/lib/mihari/database.rb +3 -5
- 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/http.rb +13 -11
- 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 +15 -6
- data/lib/mihari/web/public/assets/{index-07fafab5.js → index-07cddfcd.js} +44 -44
- data/lib/mihari/web/public/index.html +1 -1
- data/lib/mihari/web/public/redoc-static.html +381 -401
- data/lib/mihari.rb +1 -2
- data/mihari.gemspec +14 -16
- data/mkdocs.yml +14 -8
- data/requirements.txt +1 -1
- metadata +81 -39
- data/lib/mihari/mixins/error_notification.rb +0 -21
- data/lib/mihari/services/rule_runner.rb +0 -19
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"]
|
@@ -134,7 +132,7 @@ module Mihari
|
|
134
132
|
class Database
|
135
133
|
class << self
|
136
134
|
#
|
137
|
-
# DB
|
135
|
+
# DB migration
|
138
136
|
#
|
139
137
|
# @param [Symbol] direction
|
140
138
|
#
|
@@ -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/http.rb
CHANGED
@@ -9,14 +9,13 @@ module Mihari
|
|
9
9
|
#
|
10
10
|
class BetterError < ::HTTP::Feature
|
11
11
|
def wrap_response(response)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
response
|
12
|
+
return response if response.status.success?
|
13
|
+
|
14
|
+
raise StatusCodeError.new(
|
15
|
+
"Unsuccessful response code returned: #{response.code}",
|
16
|
+
response.code,
|
17
|
+
response.body.to_s
|
18
|
+
)
|
20
19
|
end
|
21
20
|
|
22
21
|
def on_error(_request, error)
|
@@ -35,12 +34,15 @@ module Mihari
|
|
35
34
|
#
|
36
35
|
# @param [Integer, nil] timeout
|
37
36
|
# @param [Hash] headers
|
37
|
+
# @param [Boolean] raise_exception
|
38
38
|
#
|
39
39
|
# @return [::HTTP::Client]
|
40
40
|
#
|
41
|
-
|
42
|
-
|
43
|
-
client.
|
41
|
+
# @param [Object] raise_exception
|
42
|
+
def build(headers: {}, timeout: nil, raise_exception: true)
|
43
|
+
client = raise_exception ? ::HTTP.use(:better_error) : ::HTTP
|
44
|
+
client = client.headers(headers)
|
45
|
+
client = client.timeout(timeout) unless timeout.nil?
|
44
46
|
client
|
45
47
|
end
|
46
48
|
end
|
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
|