mihari 3.11.0 → 3.12.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/README.md +0 -1
- data/lib/mihari/analyzers/base.rb +1 -1
- data/lib/mihari/analyzers/feed.rb +39 -0
- data/lib/mihari/analyzers/rule.rb +1 -0
- data/lib/mihari/cli/analyzer.rb +2 -0
- data/lib/mihari/commands/feed.rb +26 -0
- data/lib/mihari/database.rb +4 -4
- data/lib/mihari/enrichers/ipinfo.rb +2 -0
- data/lib/mihari/errors.rb +4 -0
- data/lib/mihari/feed/parser.rb +34 -0
- data/lib/mihari/feed/reader.rb +113 -0
- data/lib/mihari/mixins/autonomous_system.rb +2 -0
- data/lib/mihari/mixins/configuration.rb +2 -2
- data/lib/mihari/mixins/disallowed_data_value.rb +2 -0
- data/lib/mihari/mixins/rule.rb +2 -0
- data/lib/mihari/models/alert.rb +4 -5
- data/lib/mihari/models/artifact.rb +2 -3
- data/lib/mihari/models/dns.rb +2 -2
- data/lib/mihari/schemas/rule.rb +12 -1
- data/lib/mihari/status.rb +2 -2
- data/lib/mihari/structs/alert.rb +3 -1
- data/lib/mihari/structs/censys.rb +2 -0
- data/lib/mihari/structs/greynoise.rb +2 -0
- data/lib/mihari/structs/ipinfo.rb +2 -0
- data/lib/mihari/structs/onyphe.rb +2 -0
- data/lib/mihari/structs/shodan.rb +2 -0
- data/lib/mihari/structs/urlscan.rb +2 -0
- data/lib/mihari/structs/virustotal_intelligence.rb +2 -0
- data/lib/mihari/types.rb +6 -0
- data/lib/mihari/version.rb +1 -1
- data/lib/mihari/web/api.rb +2 -0
- data/lib/mihari/web/entities/artifact.rb +2 -2
- data/lib/mihari/web/entities/whois.rb +1 -1
- data/lib/mihari/web/public/index.html +1 -1
- data/lib/mihari/web/public/redoc-static.html +181 -183
- data/lib/mihari/web/public/static/js/app.5dc97aae.js +21 -0
- data/lib/mihari/web/public/static/js/app.5dc97aae.js.map +1 -0
- data/lib/mihari/web/public/static/js/app.f2b8890f.js +21 -0
- data/lib/mihari/web/public/static/js/app.f2b8890f.js.map +1 -0
- data/lib/mihari.rb +1 -0
- data/mihari.gemspec +17 -17
- data/sig/lib/mihari/analyzers/feed.rbs +23 -0
- data/sig/lib/mihari/cli/analyzer.rbs +4 -0
- data/sig/lib/mihari/commands/feed.rbs +7 -0
- data/sig/lib/mihari/feed/parser.rbs +11 -0
- data/sig/lib/mihari/feed/reader.rbs +56 -0
- data/sig/lib/mihari/structs/alert.rbs +1 -1
- data/sig/lib/mihari/types.rbs +4 -0
- metadata +90 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a17c14dffe68b2f82316858615371036996a3a2b6d31d3c6a5c431294c38634
|
4
|
+
data.tar.gz: 97afaf2f8b20985b0908cc1fe5778fe75ab7d0e1bf13b990a7b4165c92843604
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 418d7f278536e245196723d2ebbe0d99934b0db3278e8f8178470241c67f25e05d0aacf7bab2b766ce69d0589a79e87eca554a91fe4cfae5cfa12cd52d97fb61
|
7
|
+
data.tar.gz: 9e90193273ee40c9956a138c2c73b713eb610a3ebdc1c9def73a6d354c4124a97e6842e438004956b3edc3206dfee8bae5771a86e964b59a2a7065a1f910891f
|
data/README.md
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/mihari)
|
4
4
|
[](https://github.com/ninoseki/mihari/actions/workflows/test.yml)
|
5
|
-
[](https://hub.docker.com/r/ninoseki/mihari)
|
6
5
|
[](https://coveralls.io/github/ninoseki/mihari?branch=master)
|
7
6
|
[](https://www.codefactor.io/repository/github/ninoseki/mihari)
|
8
7
|
|
@@ -111,7 +111,7 @@ module Mihari
|
|
111
111
|
# @return [Array<Mihari::Artifact>]
|
112
112
|
#
|
113
113
|
def enriched_artifacts
|
114
|
-
@enriched_artifacts ||=
|
114
|
+
@enriched_artifacts ||= Parallel.map(unique_artifacts) do |artifact|
|
115
115
|
artifact.enrich_all
|
116
116
|
artifact
|
117
117
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mihari/feed/reader"
|
4
|
+
require "mihari/feed/parser"
|
5
|
+
|
6
|
+
module Mihari
|
7
|
+
module Analyzers
|
8
|
+
class Feed < Base
|
9
|
+
param :query
|
10
|
+
option :title, default: proc { "Feed" }
|
11
|
+
option :description, default: proc { "query = #{query}" }
|
12
|
+
option :tags, default: proc { [] }
|
13
|
+
|
14
|
+
option :http_request_method, default: proc { "GET" }
|
15
|
+
option :http_request_headers, default: proc { {} }
|
16
|
+
option :http_request_payload, default: proc { {} }
|
17
|
+
option :http_request_payload_type, default: proc {}
|
18
|
+
|
19
|
+
option :selector, default: proc { "" }
|
20
|
+
|
21
|
+
def artifacts
|
22
|
+
Mihari::Feed::Parser.new(data).parse selector
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def data
|
28
|
+
reader = Mihari::Feed::Reader.new(
|
29
|
+
query,
|
30
|
+
http_request_method: http_request_method,
|
31
|
+
http_request_headers: http_request_headers,
|
32
|
+
http_request_payload: http_request_payload,
|
33
|
+
http_request_payload_type: http_request_payload_type
|
34
|
+
)
|
35
|
+
reader.read
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/mihari/cli/analyzer.rb
CHANGED
@@ -6,6 +6,7 @@ require "mihari/commands/circl"
|
|
6
6
|
require "mihari/commands/crtsh"
|
7
7
|
require "mihari/commands/dnpedia"
|
8
8
|
require "mihari/commands/dnstwister"
|
9
|
+
require "mihari/commands/feed"
|
9
10
|
require "mihari/commands/greynoise"
|
10
11
|
require "mihari/commands/onyphe"
|
11
12
|
require "mihari/commands/otx"
|
@@ -35,6 +36,7 @@ module Mihari
|
|
35
36
|
include Mihari::Commands::Crtsh
|
36
37
|
include Mihari::Commands::DNPedia
|
37
38
|
include Mihari::Commands::DNSTwister
|
39
|
+
include Mihari::Commands::Feed
|
38
40
|
include Mihari::Commands::GreyNoise
|
39
41
|
include Mihari::Commands::JSON
|
40
42
|
include Mihari::Commands::Onyphe
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mihari
|
4
|
+
module Commands
|
5
|
+
module Feed
|
6
|
+
def self.included(thor)
|
7
|
+
thor.class_eval do
|
8
|
+
desc "feed [URL]", "ingest feed"
|
9
|
+
method_option :title, type: :string, desc: "title"
|
10
|
+
method_option :description, type: :string, desc: "description"
|
11
|
+
method_option :tags, type: :array, desc: "tags"
|
12
|
+
method_option :http_request_method, type: :string, desc: "HTTP request method"
|
13
|
+
method_option :http_request_headers, type: :hash, desc: "HTTP request headers"
|
14
|
+
method_option :http_request_payload_type, type: :string, desc: "HTTP request payload type"
|
15
|
+
method_option :http_request_payload, type: :hash, desc: "HTTP request payload"
|
16
|
+
method_option :selector, type: :string, desc: "jr selector", required: true
|
17
|
+
def feed(query)
|
18
|
+
with_error_handling do
|
19
|
+
run_analyzer Analyzers::Feed, query: query, options: options
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/mihari/database.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "active_record"
|
4
4
|
|
5
|
-
class InitialSchema < ActiveRecord::Migration[
|
5
|
+
class InitialSchema < ActiveRecord::Migration[7.0]
|
6
6
|
def change
|
7
7
|
create_table :tags, if_not_exists: true do |t|
|
8
8
|
t.string :name, null: false
|
@@ -32,13 +32,13 @@ class InitialSchema < ActiveRecord::Migration[6.1]
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
class AddeSourceToArtifactSchema < ActiveRecord::Migration[
|
35
|
+
class AddeSourceToArtifactSchema < ActiveRecord::Migration[7.0]
|
36
36
|
def change
|
37
37
|
add_column :artifacts, :source, :string, if_not_exists: true
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
class EnrichmentsSchema < ActiveRecord::Migration[
|
41
|
+
class EnrichmentsSchema < ActiveRecord::Migration[7.0]
|
42
42
|
def change
|
43
43
|
create_table :autonomous_systems, if_not_exists: true do |t|
|
44
44
|
t.integer :asn, null: false
|
@@ -74,7 +74,7 @@ class EnrichmentsSchema < ActiveRecord::Migration[6.1]
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
class EnrichmentCreatedAtSchema < ActiveRecord::Migration[
|
77
|
+
class EnrichmentCreatedAtSchema < ActiveRecord::Migration[7.0]
|
78
78
|
def change
|
79
79
|
# Add created_at column because now it is able to enrich an atrifact after the creation
|
80
80
|
add_column :autonomous_systems, :created_at, :datetime, if_not_exists: true
|
data/lib/mihari/errors.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "jr/cli/core_ext"
|
4
|
+
|
5
|
+
module Mihari
|
6
|
+
module Feed
|
7
|
+
class Parser
|
8
|
+
attr_reader :data
|
9
|
+
|
10
|
+
#
|
11
|
+
# @param [Array<Hash>, Array<Array<String>>] data
|
12
|
+
#
|
13
|
+
def initialize(data)
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Parse data by selector
|
19
|
+
#
|
20
|
+
# @param [String] selector
|
21
|
+
#
|
22
|
+
# @return [Array<String>]
|
23
|
+
#
|
24
|
+
def parse(selector)
|
25
|
+
parsed = data.instance_eval(selector)
|
26
|
+
|
27
|
+
raise FeedParseError unless parsed.is_a?(Array) || parsed.is_a?(Enumerator)
|
28
|
+
raise FeedParseError unless parsed.all?(String)
|
29
|
+
|
30
|
+
parsed.to_a
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "csv"
|
4
|
+
require "json"
|
5
|
+
require "net/https"
|
6
|
+
require "uri"
|
7
|
+
|
8
|
+
module Mihari
|
9
|
+
module Feed
|
10
|
+
class Reader
|
11
|
+
attr_reader :uri, :http_request_headers, :http_request_method, :http_request_payload_type, :http_request_payload
|
12
|
+
|
13
|
+
def initialize(url, http_request_headers: {}, http_request_method: "GET", http_request_payload_type: nil, http_request_payload: {})
|
14
|
+
@uri = URI(url)
|
15
|
+
@http_request_headers = http_request_headers
|
16
|
+
@http_request_method = http_request_method
|
17
|
+
@http_request_payload_type = http_request_payload_type
|
18
|
+
@http_request_payload = http_request_payload
|
19
|
+
end
|
20
|
+
|
21
|
+
def read
|
22
|
+
return get if http_request_method == "GET"
|
23
|
+
|
24
|
+
post
|
25
|
+
end
|
26
|
+
|
27
|
+
def get
|
28
|
+
uri.query = URI.encode_www_form(http_request_payload)
|
29
|
+
get = Net::HTTP::Get.new(uri)
|
30
|
+
|
31
|
+
request(get)
|
32
|
+
end
|
33
|
+
|
34
|
+
def post
|
35
|
+
post = Net::HTTP::Post.new(uri)
|
36
|
+
|
37
|
+
case http_request_payload_type
|
38
|
+
when "application/json"
|
39
|
+
post.body = JSON.generate(http_request_payload)
|
40
|
+
when "application/x-www-form-urlencoded"
|
41
|
+
post.set_form_data(http_request_payload)
|
42
|
+
end
|
43
|
+
|
44
|
+
request(post)
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Convert text as JSON
|
49
|
+
#
|
50
|
+
# @param [String] text
|
51
|
+
#
|
52
|
+
# @return [Array<Hash>]
|
53
|
+
#
|
54
|
+
def convert_as_json(text)
|
55
|
+
data = JSON.parse(text, symbolize_names: true)
|
56
|
+
return data if data.is_a?(Array)
|
57
|
+
|
58
|
+
[data]
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Convert text as CSV
|
63
|
+
#
|
64
|
+
# @param [String] text
|
65
|
+
#
|
66
|
+
# @return [Array<Hash>]
|
67
|
+
#
|
68
|
+
def convert_as_csv(text)
|
69
|
+
text_without_comments = text.lines.reject { |line| line.start_with? "#" }.join("\n")
|
70
|
+
|
71
|
+
CSV.new(text_without_comments).to_a.reject(&:empty?)
|
72
|
+
end
|
73
|
+
|
74
|
+
def https_options
|
75
|
+
return { use_ssl: true } if uri.scheme == "https"
|
76
|
+
|
77
|
+
{}
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Make a HTTP request
|
82
|
+
#
|
83
|
+
# @param [Net::HTTPRequest] req
|
84
|
+
#
|
85
|
+
# @return [Array<Hash>]
|
86
|
+
#
|
87
|
+
def request(req)
|
88
|
+
Net::HTTP.start(uri.host, uri.port, https_options) do |http|
|
89
|
+
# set headers
|
90
|
+
http_request_headers.each do |k, v|
|
91
|
+
req[k] = v
|
92
|
+
end
|
93
|
+
|
94
|
+
response = http.request(req)
|
95
|
+
|
96
|
+
code = response.code.to_i
|
97
|
+
raise HttpError, "Unsupported response code returned: #{code}" if code != 200
|
98
|
+
|
99
|
+
body = response.body
|
100
|
+
|
101
|
+
content_type = response["Content-Type"].to_s
|
102
|
+
data = if content_type.include?("application/json")
|
103
|
+
convert_as_json(body)
|
104
|
+
else
|
105
|
+
convert_as_csv(body)
|
106
|
+
end
|
107
|
+
|
108
|
+
data
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -51,9 +51,9 @@ module Mihari
|
|
51
51
|
# @return [String] A template for config
|
52
52
|
#
|
53
53
|
def config_template
|
54
|
-
config = Mihari.config.values.keys.
|
54
|
+
config = Mihari.config.values.keys.to_h do |key|
|
55
55
|
[key.to_s, nil]
|
56
|
-
end
|
56
|
+
end
|
57
57
|
|
58
58
|
YAML.dump(config)
|
59
59
|
end
|
data/lib/mihari/mixins/rule.rb
CHANGED
data/lib/mihari/models/alert.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_record"
|
4
|
-
require "active_record/filter"
|
5
4
|
|
6
5
|
module Mihari
|
7
6
|
class Alert < ActiveRecord::Base
|
@@ -55,7 +54,7 @@ module Mihari
|
|
55
54
|
artifact = artifact.where(dns_records: { value: filter.dns_record }) if filter.dns_record
|
56
55
|
artifact = artifact.where(reverse_dns_names: { name: filter.reverse_dns_name }) if filter.reverse_dns_name
|
57
56
|
# get artifact ids if there is any valid filter for artifact
|
58
|
-
if filter.
|
57
|
+
if filter.valid_artifact_filters?
|
59
58
|
artifact_ids = artifact.pluck(:id)
|
60
59
|
# set invalid ID if nothing is matched with the filters
|
61
60
|
artifact_ids = [-1] if artifact_ids.empty?
|
@@ -70,10 +69,10 @@ module Mihari
|
|
70
69
|
relation = relation.where(source: filter.source) if filter.source
|
71
70
|
relation = relation.where(title: filter.title) if filter.title
|
72
71
|
|
73
|
-
relation = relation.
|
72
|
+
relation = relation.where("description LIKE ?", "%#{filter.description}%") if filter.description
|
74
73
|
|
75
|
-
relation = relation.
|
76
|
-
relation = relation.
|
74
|
+
relation = relation.where("alerts.created_at >= ?", filter.from_at) if filter.from_at
|
75
|
+
relation = relation.where("alerts.created_at <= ?", filter.to_at) if filter.to_at
|
77
76
|
|
78
77
|
relation
|
79
78
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_record"
|
4
|
-
require "active_record/filter"
|
5
4
|
require "active_support/core_ext/integer/time"
|
6
5
|
require "active_support/core_ext/numeric/time"
|
7
|
-
require "uri"
|
6
|
+
require "addressable/uri"
|
8
7
|
|
9
8
|
class ArtifactValidator < ActiveModel::Validator
|
10
9
|
def validate(record)
|
@@ -119,7 +118,7 @@ module Mihari
|
|
119
118
|
def normalize_as_domain(url_or_domain)
|
120
119
|
return url_or_domain if data_type == "domain"
|
121
120
|
|
122
|
-
URI.parse(url_or_domain).host
|
121
|
+
Addressable::URI.parse(url_or_domain).host
|
123
122
|
end
|
124
123
|
|
125
124
|
def can_enrich_whois?
|
data/lib/mihari/models/dns.rb
CHANGED
@@ -37,7 +37,7 @@ module Mihari
|
|
37
37
|
resources = Resolv::DNS.new.getresources(domain, resource_type)
|
38
38
|
resource_name = resource_type.to_s.split("::").last
|
39
39
|
|
40
|
-
resources.
|
40
|
+
resources.filter_map do |resource|
|
41
41
|
# A, AAAA
|
42
42
|
if resource.respond_to?(:address)
|
43
43
|
new(resource: resource_name, value: resource.address.to_s)
|
@@ -48,7 +48,7 @@ module Mihari
|
|
48
48
|
elsif resource.respond_to?(:data)
|
49
49
|
new(resource: resource_name, value: resource.data.to_s)
|
50
50
|
end
|
51
|
-
end
|
51
|
+
end
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/lib/mihari/schemas/rule.rb
CHANGED
@@ -44,6 +44,17 @@ module Mihari
|
|
44
44
|
optional(:options).hash(AnalyzerOptions)
|
45
45
|
end
|
46
46
|
|
47
|
+
Feed = Dry::Schema.Params do
|
48
|
+
required(:analyzer).value(Types::String.enum("feed"))
|
49
|
+
required(:query).value(:string)
|
50
|
+
required(:http_request_method).value(Types::FeedHttpRequestMethods).default("GET")
|
51
|
+
required(:http_request_headers).value(:hash).default({})
|
52
|
+
required(:http_request_payload).value(:hash).default({})
|
53
|
+
required(:selector).value(:string)
|
54
|
+
optional(:http_request_payload_type).value(Types::FeedHttpRequestPayloadTypes)
|
55
|
+
optional(:options).hash(AnalyzerOptions)
|
56
|
+
end
|
57
|
+
|
47
58
|
Rule = Dry::Schema.Params do
|
48
59
|
required(:title).value(:string)
|
49
60
|
required(:description).value(:string)
|
@@ -55,7 +66,7 @@ module Mihari
|
|
55
66
|
optional(:created_on).value(:date)
|
56
67
|
optional(:updated_on).value(:date)
|
57
68
|
|
58
|
-
required(:queries).value(:array).each { Analyzer | Spyse | ZoomEye | Urlscan | Crtsh }
|
69
|
+
required(:queries).value(:array).each { Analyzer | Spyse | ZoomEye | Urlscan | Crtsh | Feed }
|
59
70
|
|
60
71
|
optional(:allowed_data_types).value(array[Types::DataTypes]).default(ALLOWED_DATA_TYPES)
|
61
72
|
optional(:disallowed_data_values).value(array[:string]).default([])
|
data/lib/mihari/status.rb
CHANGED
@@ -18,11 +18,11 @@ module Mihari
|
|
18
18
|
# @return [Array<Hash>]
|
19
19
|
#
|
20
20
|
def statuses
|
21
|
-
(Mihari.analyzers + Mihari.emitters + Mihari.enrichers).
|
21
|
+
(Mihari.analyzers + Mihari.emitters + Mihari.enrichers).to_h do |klass|
|
22
22
|
name = klass.to_s.split("::").last.to_s
|
23
23
|
|
24
24
|
[name, build_status(klass)]
|
25
|
-
end.
|
25
|
+
end.compact
|
26
26
|
end
|
27
27
|
|
28
28
|
#
|
data/lib/mihari/structs/alert.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "json"
|
2
4
|
require "dry/struct"
|
3
5
|
|
@@ -16,7 +18,7 @@ module Mihari
|
|
16
18
|
attribute? :dns_record, Types::String.optional
|
17
19
|
attribute? :reverse_dns_name, Types::String.optional
|
18
20
|
|
19
|
-
def
|
21
|
+
def valid_artifact_filters?
|
20
22
|
!(artifact_data || asn || dns_record || reverse_dns_name).nil?
|
21
23
|
end
|
22
24
|
end
|
data/lib/mihari/types.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "dry/types"
|
2
4
|
|
3
5
|
module Mihari
|
@@ -22,6 +24,7 @@ module Mihari
|
|
22
24
|
"circl",
|
23
25
|
"dnpedia",
|
24
26
|
"dnstwister",
|
27
|
+
"feed",
|
25
28
|
"greynoise",
|
26
29
|
"onyphe",
|
27
30
|
"otx",
|
@@ -36,5 +39,8 @@ module Mihari
|
|
36
39
|
"vt_intel",
|
37
40
|
"vt"
|
38
41
|
)
|
42
|
+
|
43
|
+
FeedHttpRequestMethods = Types::String.enum("GET", "POST")
|
44
|
+
FeedHttpRequestPayloadTypes = Types::String.enum("application/json", "application/x-www-form-urlencoded")
|
39
45
|
end
|
40
46
|
end
|
data/lib/mihari/version.rb
CHANGED
data/lib/mihari/web/api.rb
CHANGED
@@ -14,10 +14,10 @@ module Mihari
|
|
14
14
|
expose :whois_record, using: Entities::WhoisRecord, documentation: { type: Entities::WhoisRecord, required: false }, as: :whoisRecord
|
15
15
|
|
16
16
|
expose :reverse_dns_names, using: Entities::ReverseDnsName, documentation: { type: Entities::ReverseDnsName, is_array: true, required: false }, as: :reverseDnsNames do |status, _options|
|
17
|
-
status.reverse_dns_names.
|
17
|
+
status.reverse_dns_names.empty? ? nil : status.reverse_dns_names
|
18
18
|
end
|
19
19
|
expose :dns_records, using: Entities::DnsRecord, documentation: { type: Entities::DnsRecord, is_array: true, required: false }, as: :dnsRecords do |status, _options|
|
20
|
-
status.dns_records.
|
20
|
+
status.dns_records.empty? ? nil : status.dns_records
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -9,7 +9,7 @@ module Mihari
|
|
9
9
|
expose :expires_on, documentation: { type: Date, required: false }, as: :expiresOn
|
10
10
|
expose :registrar, documentation: { type: Hash, required: false }
|
11
11
|
expose :contacts, documentation: { type: Hash, is_array: true, required: true } do |whois_record, _options|
|
12
|
-
whois_record.contacts.map
|
12
|
+
whois_record.contacts.map(&:to_camelback_keys)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -1 +1 @@
|
|
1
|
-
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/static/favicon.ico"><title>Mihari</title><link href="/static/js/app.
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/static/favicon.ico"><title>Mihari</title><link href="/static/js/app.5dc97aae.js" rel="preload" as="script"></head><body><noscript><strong>We're sorry but Mihari doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/app.5dc97aae.js"></script></body></html>
|