hachi 1.0.0 → 2.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/.github/workflows/test.yml +10 -13
- data/.gitignore +5 -1
- data/README.md +10 -84
- data/hachi.gemspec +7 -5
- data/lib/hachi/api.rb +31 -7
- data/lib/hachi/awrence/methods.rb +66 -0
- data/lib/hachi/clients/alert.rb +9 -119
- data/lib/hachi/clients/artifact.rb +3 -38
- data/lib/hachi/clients/base.rb +28 -26
- data/lib/hachi/clients/case.rb +9 -102
- data/lib/hachi/clients/observable.rb +53 -0
- data/lib/hachi/clients/query.rb +18 -0
- data/lib/hachi/clients/user.rb +6 -16
- data/lib/hachi/version.rb +1 -1
- data/lib/hachi.rb +15 -6
- metadata +45 -23
- data/lib/hachi/models/alert.rb +0 -63
- data/lib/hachi/models/artifact.rb +0 -40
- data/lib/hachi/models/base.rb +0 -31
- data/lib/hachi/models/case.rb +0 -54
- data/lib/hachi/models/user.rb +0 -36
- data/samples/01_create_an_alert.rb +0 -17
- data/samples/02_search_artifacts.rb +0 -16
- data/samples/03_list_cases.rb +0 -16
- data/samples/04_merge_alerts.rb +0 -17
data/lib/hachi/clients/base.rb
CHANGED
@@ -7,11 +7,21 @@ require "uri"
|
|
7
7
|
module Hachi
|
8
8
|
module Clients
|
9
9
|
class Base
|
10
|
-
|
10
|
+
# @return [String]
|
11
|
+
attr_reader :api_endpoint
|
11
12
|
|
12
|
-
|
13
|
+
# @return [String]
|
14
|
+
attr_reader :api_key
|
15
|
+
|
16
|
+
# @return [String, nil]
|
17
|
+
attr_reader :api_version
|
18
|
+
|
19
|
+
include Hachi::Awrence::Methods
|
20
|
+
|
21
|
+
def initialize(api_endpoint:, api_key:, api_version:)
|
13
22
|
@api_endpoint = URI(api_endpoint)
|
14
23
|
@api_key = api_key
|
24
|
+
@api_version = api_version
|
15
25
|
end
|
16
26
|
|
17
27
|
def get(path, params: {}, &block)
|
@@ -27,6 +37,8 @@ module Hachi
|
|
27
37
|
url = url_for(path)
|
28
38
|
url.query = URI.encode_www_form(params) unless params.empty?
|
29
39
|
|
40
|
+
json = to_camelback_keys(json.compact) if json.is_a?(Hash)
|
41
|
+
|
30
42
|
post = Net::HTTP::Post.new(url)
|
31
43
|
post.body = json.is_a?(Hash) ? json.to_json : json.to_s
|
32
44
|
|
@@ -40,6 +52,8 @@ module Hachi
|
|
40
52
|
url = url_for(path)
|
41
53
|
url.query = URI.encode_www_form(params) unless params.empty?
|
42
54
|
|
55
|
+
json = to_camelback_keys(json.compact) if json.is_a?(Hash)
|
56
|
+
|
43
57
|
delete = Net::HTTP::Delete.new(url)
|
44
58
|
delete.body = json.is_a?(Hash) ? json.to_json : json.to_s
|
45
59
|
|
@@ -51,6 +65,8 @@ module Hachi
|
|
51
65
|
url = url_for(path)
|
52
66
|
url.query = URI.encode_www_form(params) unless params.empty?
|
53
67
|
|
68
|
+
json = to_camelback_keys(json.compact) if json.is_a?(Hash)
|
69
|
+
|
54
70
|
patch = Net::HTTP::Patch.new(url)
|
55
71
|
patch.body = json.is_a?(Hash) ? json.to_json : json.to_s
|
56
72
|
|
@@ -63,7 +79,11 @@ module Hachi
|
|
63
79
|
private
|
64
80
|
|
65
81
|
def base_url
|
66
|
-
|
82
|
+
if api_version.nil? || api_version.to_s.empty?
|
83
|
+
"#{api_endpoint.scheme}://#{api_endpoint.hostname}:#{api_endpoint.port}/api"
|
84
|
+
else
|
85
|
+
"#{api_endpoint.scheme}://#{api_endpoint.hostname}:#{api_endpoint.port}/api/#{api_version}"
|
86
|
+
end
|
67
87
|
end
|
68
88
|
|
69
89
|
def url_for(path)
|
@@ -73,13 +93,13 @@ module Hachi
|
|
73
93
|
def https_options
|
74
94
|
return nil if api_endpoint.scheme != "https"
|
75
95
|
|
76
|
-
if proxy = ENV
|
96
|
+
if proxy = ENV.fetch("HTTPS_PROXY") { ENV.fetch("https_proxy", nil) }
|
77
97
|
uri = URI(proxy)
|
78
98
|
{
|
79
99
|
proxy_address: uri.hostname,
|
80
100
|
proxy_port: uri.port,
|
81
101
|
proxy_from_env: false,
|
82
|
-
use_ssl: true
|
102
|
+
use_ssl: true
|
83
103
|
}
|
84
104
|
else
|
85
105
|
{ use_ssl: true }
|
@@ -87,12 +107,12 @@ module Hachi
|
|
87
107
|
end
|
88
108
|
|
89
109
|
def http_options
|
90
|
-
if proxy = ENV
|
110
|
+
if proxy = ENV.fetch("HTTP_PROXY") { ENV.fetch("http_proxy", nil) }
|
91
111
|
uri = URI(proxy)
|
92
112
|
{
|
93
113
|
proxy_address: uri.hostname,
|
94
114
|
proxy_port: uri.port,
|
95
|
-
proxy_from_env: false
|
115
|
+
proxy_from_env: false
|
96
116
|
}
|
97
117
|
else
|
98
118
|
{}
|
@@ -119,26 +139,8 @@ module Hachi
|
|
119
139
|
end
|
120
140
|
end
|
121
141
|
|
122
|
-
def validate_range(range)
|
123
|
-
return true if range == "all"
|
124
|
-
raise ArgumentError, "range should be 'all' or `from-to`" unless range.match?(/(\d+)-(\d+)/)
|
125
|
-
|
126
|
-
from, to = range.split("-").map(&:to_i)
|
127
|
-
return true if from < to
|
128
|
-
|
129
|
-
raise ArgumentError, "from should be smaller than to"
|
130
|
-
end
|
131
|
-
|
132
|
-
def _search(path, query:, range: "all", sort: nil)
|
133
|
-
validate_range range
|
134
|
-
|
135
|
-
query_string = build_query_string(range: range, sort: sort)
|
136
|
-
|
137
|
-
post("#{path}?#{query_string}", json: { query: query }) { |json| json }
|
138
|
-
end
|
139
|
-
|
140
142
|
def build_query_string(params)
|
141
|
-
URI.encode_www_form(params.
|
143
|
+
URI.encode_www_form(params.compact)
|
142
144
|
end
|
143
145
|
end
|
144
146
|
end
|
data/lib/hachi/clients/case.rb
CHANGED
@@ -3,15 +3,6 @@
|
|
3
3
|
module Hachi
|
4
4
|
module Clients
|
5
5
|
class Case < Base
|
6
|
-
#
|
7
|
-
# List cases
|
8
|
-
#
|
9
|
-
# @return [Array]
|
10
|
-
#
|
11
|
-
def list
|
12
|
-
get("/api/case") { |json| json }
|
13
|
-
end
|
14
|
-
|
15
6
|
#
|
16
7
|
# Get a case
|
17
8
|
#
|
@@ -20,7 +11,7 @@ module Hachi
|
|
20
11
|
# @return [Hash]
|
21
12
|
#
|
22
13
|
def get_by_id(id)
|
23
|
-
get("/
|
14
|
+
get("/case/#{id}") { |json| json }
|
24
15
|
end
|
25
16
|
|
26
17
|
#
|
@@ -31,114 +22,30 @@ module Hachi
|
|
31
22
|
# @return [String]
|
32
23
|
#
|
33
24
|
def delete_by_id(id)
|
34
|
-
delete("/
|
25
|
+
delete("/case/#{id}") { |json| json }
|
35
26
|
end
|
36
27
|
|
37
28
|
#
|
38
29
|
# Create a case
|
39
30
|
#
|
40
|
-
# @param [
|
41
|
-
# @param [String, nil] description
|
42
|
-
# @param [Integer, nil] severity
|
43
|
-
# @param [String, nil] start_date
|
44
|
-
# @param [String, nil] owner
|
45
|
-
# @param [Boolean, nil] flag
|
46
|
-
# @param [Intege, nil] tlp
|
47
|
-
# @param [String, nil] tags
|
48
|
-
#
|
49
|
-
# @return [Hash]
|
50
|
-
#
|
51
|
-
def create(title:, description:, severity: nil, start_date: nil, owner: nil, flag: nil, tlp: nil, tags: nil)
|
52
|
-
kase = Models::Case.new(
|
53
|
-
title: title,
|
54
|
-
description: description,
|
55
|
-
severity: severity,
|
56
|
-
start_date: start_date,
|
57
|
-
owner: owner,
|
58
|
-
flag: flag,
|
59
|
-
tlp: tlp,
|
60
|
-
tags: tags,
|
61
|
-
)
|
62
|
-
|
63
|
-
post("/api/case", json: kase.payload) { |json| json }
|
64
|
-
end
|
65
|
-
|
66
|
-
#
|
67
|
-
# Find cases
|
68
|
-
#
|
69
|
-
# @param [Hash] query
|
70
|
-
# @param [String] range
|
71
|
-
#
|
72
|
-
# @return [Hash]
|
73
|
-
#
|
74
|
-
def search(query, range: "all")
|
75
|
-
_search("/api/case/_search", query: query, range: range) { |json| json }
|
76
|
-
end
|
77
|
-
|
78
|
-
#
|
79
|
-
# Get list of cases linked to this case
|
80
|
-
#
|
81
|
-
# @param [String] id Case ID
|
82
|
-
#
|
83
|
-
# @return [Array]
|
84
|
-
#
|
85
|
-
def links(id)
|
86
|
-
get("/api/case/#{id}/links") { |json| json }
|
87
|
-
end
|
88
|
-
|
89
|
-
#
|
90
|
-
# Merge two cases
|
91
|
-
#
|
92
|
-
# @param [String] id1 Case ID
|
93
|
-
# @param [String] id2 Case ID
|
31
|
+
# @param [Hash] payload
|
94
32
|
#
|
95
33
|
# @return [Hash]
|
96
34
|
#
|
97
|
-
def
|
98
|
-
post("/
|
35
|
+
def create(**payload)
|
36
|
+
post("/case", json: payload) { |json| json }
|
99
37
|
end
|
100
38
|
|
101
39
|
#
|
102
40
|
# Update a case
|
103
41
|
#
|
104
|
-
# @param [String
|
105
|
-
# @param [
|
106
|
-
# @param [String, nil] description
|
107
|
-
# @param [String, nil] severity
|
108
|
-
# @param [String, nil] start_date
|
109
|
-
# @param [String, nil] owner
|
110
|
-
# @param [Boolean, nil] flag
|
111
|
-
# @param [Integer, nil] tlp
|
112
|
-
# @param [String, nil] tags
|
113
|
-
# @param [String, nil] status
|
114
|
-
# @param [String, nil] resolution_status
|
115
|
-
# @param [String, nil] impact_status
|
116
|
-
# @param [String, nil] summary
|
117
|
-
# @param [String, nil] end_date
|
118
|
-
# @param [String, nil] metrics
|
119
|
-
# @param [String, nil] custom_fields
|
42
|
+
# @param [String] id
|
43
|
+
# @param [Hash] payload
|
120
44
|
#
|
121
45
|
# @return [Hash]
|
122
46
|
#
|
123
|
-
def update(id,
|
124
|
-
|
125
|
-
title: title,
|
126
|
-
description: description,
|
127
|
-
severity: severity,
|
128
|
-
startDate: start_date,
|
129
|
-
owner: owner,
|
130
|
-
flag: flag,
|
131
|
-
tlp: tlp,
|
132
|
-
tags: tags,
|
133
|
-
status: status,
|
134
|
-
resolutionStatus: resolution_status,
|
135
|
-
impactStatus: impact_status,
|
136
|
-
summary: summary,
|
137
|
-
endDate: end_date,
|
138
|
-
metrics: metrics,
|
139
|
-
customFields: custom_fields
|
140
|
-
}.compact
|
141
|
-
patch("/api/case/#{id}", json: attributes) { |json| json }
|
47
|
+
def update(id, **payload)
|
48
|
+
patch("/case/#{id}", json: payload) { |json| json }
|
142
49
|
end
|
143
50
|
end
|
144
51
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hachi
|
4
|
+
module Clients
|
5
|
+
class Observable < Base
|
6
|
+
#
|
7
|
+
# Create an observable in a case
|
8
|
+
#
|
9
|
+
# @param [String] case_id Observable ID
|
10
|
+
# @param [Hash] payload
|
11
|
+
#
|
12
|
+
# @return [Hash]
|
13
|
+
#
|
14
|
+
def create_in_case(case_id, **payload)
|
15
|
+
post("/case/#{case_id}/observable", json: payload) { |json| json }
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Create an observable in an alert
|
20
|
+
#
|
21
|
+
# @param [String] alert_id Observable ID
|
22
|
+
# @param [Hash] payload
|
23
|
+
#
|
24
|
+
# @return [Hash]
|
25
|
+
#
|
26
|
+
def create_in_alert(alert_id, **payload)
|
27
|
+
post("/alert/#{alert_id}/observable", json: payload) { |json| json }
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Get an observable
|
32
|
+
#
|
33
|
+
# @param [String] id observable ID
|
34
|
+
#
|
35
|
+
# @return [Hash]
|
36
|
+
#
|
37
|
+
def get_by_id(id)
|
38
|
+
get("/observable/#{id}") { |json| json }
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Delete an observable
|
43
|
+
#
|
44
|
+
# @param [String] id observable ID
|
45
|
+
#
|
46
|
+
# @return [String]
|
47
|
+
#
|
48
|
+
def delete_by_id(id)
|
49
|
+
delete("/observable/#{id}") { |json| json }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hachi
|
4
|
+
module Clients
|
5
|
+
class Query < Base
|
6
|
+
#
|
7
|
+
# Query
|
8
|
+
#
|
9
|
+
# @param [Hash] payload
|
10
|
+
#
|
11
|
+
# @return [Hash]
|
12
|
+
#
|
13
|
+
def query(**payload)
|
14
|
+
post("/query", json: payload) { |json| json }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/hachi/clients/user.rb
CHANGED
@@ -9,7 +9,7 @@ module Hachi
|
|
9
9
|
# @return [Hash]
|
10
10
|
#
|
11
11
|
def current
|
12
|
-
get("/
|
12
|
+
get("/user/current") { |json| json }
|
13
13
|
end
|
14
14
|
|
15
15
|
#
|
@@ -20,7 +20,7 @@ module Hachi
|
|
20
20
|
# @return [Hash]
|
21
21
|
#
|
22
22
|
def get_by_id(id)
|
23
|
-
get("/
|
23
|
+
get("/user/#{id}") { |json| json }
|
24
24
|
end
|
25
25
|
|
26
26
|
#
|
@@ -31,28 +31,18 @@ module Hachi
|
|
31
31
|
# @return [String]
|
32
32
|
#
|
33
33
|
def delete_by_id(id)
|
34
|
-
delete("/
|
34
|
+
delete("/user/#{id}") { |json| json }
|
35
35
|
end
|
36
36
|
|
37
37
|
#
|
38
38
|
# Create a user
|
39
39
|
#
|
40
|
-
# @param [
|
41
|
-
# @param [String] name
|
42
|
-
# @param [Array<String>] roles
|
43
|
-
# @param [String] password
|
40
|
+
# @param [Hash] payload
|
44
41
|
#
|
45
42
|
# @return [Hash]
|
46
43
|
#
|
47
|
-
def create(
|
48
|
-
user
|
49
|
-
login: login,
|
50
|
-
name: name,
|
51
|
-
roles: roles,
|
52
|
-
password: password
|
53
|
-
)
|
54
|
-
|
55
|
-
post("/api/user", json: user.payload) { |json| json }
|
44
|
+
def create(**payload)
|
45
|
+
post("/user", json: payload) { |json| json }
|
56
46
|
end
|
57
47
|
end
|
58
48
|
end
|
data/lib/hachi/version.rb
CHANGED
data/lib/hachi.rb
CHANGED
@@ -2,20 +2,29 @@
|
|
2
2
|
|
3
3
|
require "hachi/version"
|
4
4
|
|
5
|
-
require "hachi/
|
5
|
+
require "hachi/awrence/methods"
|
6
6
|
|
7
|
-
require "hachi/
|
8
|
-
require "hachi/models/alert"
|
9
|
-
require "hachi/models/artifact"
|
10
|
-
require "hachi/models/case"
|
11
|
-
require "hachi/models/user"
|
7
|
+
require "hachi/api"
|
12
8
|
|
13
9
|
require "hachi/clients/base"
|
10
|
+
|
14
11
|
require "hachi/clients/alert"
|
15
12
|
require "hachi/clients/artifact"
|
16
13
|
require "hachi/clients/case"
|
14
|
+
require "hachi/clients/observable"
|
15
|
+
require "hachi/clients/query"
|
17
16
|
require "hachi/clients/user"
|
18
17
|
|
19
18
|
module Hachi
|
19
|
+
module Awrence
|
20
|
+
class << self
|
21
|
+
attr_writer :acronyms
|
22
|
+
|
23
|
+
def acronyms
|
24
|
+
@acronyms ||= {}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
20
29
|
class Error < StandardError; end
|
21
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hachi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manabu Niseki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,28 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
26
|
+
version: '2.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: coveralls_reborn
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
33
|
+
version: '0.24'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0.
|
40
|
+
version: '0.24'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: dotenv
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.7'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,42 +72,56 @@ dependencies:
|
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '3.
|
75
|
+
version: '3.11'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.11'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov-lcov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.8.0
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
94
|
- - "~>"
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
96
|
+
version: 0.8.0
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: vcr
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
72
100
|
requirements:
|
73
101
|
- - "~>"
|
74
102
|
- !ruby/object:Gem::Version
|
75
|
-
version: '6.
|
103
|
+
version: '6.1'
|
76
104
|
type: :development
|
77
105
|
prerelease: false
|
78
106
|
version_requirements: !ruby/object:Gem::Requirement
|
79
107
|
requirements:
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
|
-
version: '6.
|
110
|
+
version: '6.1'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: webmock
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
86
114
|
requirements:
|
87
115
|
- - "~>"
|
88
116
|
- !ruby/object:Gem::Version
|
89
|
-
version: '3.
|
117
|
+
version: '3.14'
|
90
118
|
type: :development
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
93
121
|
requirements:
|
94
122
|
- - "~>"
|
95
123
|
- !ruby/object:Gem::Version
|
96
|
-
version: '3.
|
124
|
+
version: '3.14'
|
97
125
|
description: A dead simple TheHive API wrapper.
|
98
126
|
email:
|
99
127
|
- manabu.niseki@gmail.com
|
@@ -113,22 +141,16 @@ files:
|
|
113
141
|
- hachi.gemspec
|
114
142
|
- lib/hachi.rb
|
115
143
|
- lib/hachi/api.rb
|
144
|
+
- lib/hachi/awrence/methods.rb
|
116
145
|
- lib/hachi/clients/alert.rb
|
117
146
|
- lib/hachi/clients/artifact.rb
|
118
147
|
- lib/hachi/clients/base.rb
|
119
148
|
- lib/hachi/clients/case.rb
|
149
|
+
- lib/hachi/clients/observable.rb
|
150
|
+
- lib/hachi/clients/query.rb
|
120
151
|
- lib/hachi/clients/user.rb
|
121
|
-
- lib/hachi/models/alert.rb
|
122
|
-
- lib/hachi/models/artifact.rb
|
123
|
-
- lib/hachi/models/base.rb
|
124
|
-
- lib/hachi/models/case.rb
|
125
|
-
- lib/hachi/models/user.rb
|
126
152
|
- lib/hachi/version.rb
|
127
153
|
- renovate.json
|
128
|
-
- samples/01_create_an_alert.rb
|
129
|
-
- samples/02_search_artifacts.rb
|
130
|
-
- samples/03_list_cases.rb
|
131
|
-
- samples/04_merge_alerts.rb
|
132
154
|
homepage: https://github.com/ninoseki/hachi
|
133
155
|
licenses:
|
134
156
|
- MIT
|
@@ -148,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
170
|
- !ruby/object:Gem::Version
|
149
171
|
version: '0'
|
150
172
|
requirements: []
|
151
|
-
rubygems_version: 3.2.
|
173
|
+
rubygems_version: 3.2.14
|
152
174
|
signing_key:
|
153
175
|
specification_version: 4
|
154
176
|
summary: A dead simple TheHive API wrapper.
|
data/lib/hachi/models/alert.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "date"
|
4
|
-
require "securerandom"
|
5
|
-
|
6
|
-
module Hachi
|
7
|
-
module Models
|
8
|
-
class Alert < Base
|
9
|
-
attr_reader :title, :description, :severity, :date, :tags, :tlp, :status, :type, :source, :source_ref, :artifacts, :follow
|
10
|
-
|
11
|
-
def initialize(title:, description:, type:, source:, severity: nil, date: nil, tags: nil, tlp: nil, status: nil, source_ref: nil, artifacts: nil, follow: nil)
|
12
|
-
@title = title
|
13
|
-
@description = description
|
14
|
-
@severity = severity
|
15
|
-
@date = date
|
16
|
-
@tags = tags
|
17
|
-
@tlp = tlp
|
18
|
-
@status = status
|
19
|
-
@type = type
|
20
|
-
@source = source
|
21
|
-
@source_ref = source_ref || SecureRandom.hex(10)
|
22
|
-
@artifacts = artifacts.nil? ? nil : artifacts.map { |a| Artifact.new(**a) }
|
23
|
-
@follow = follow
|
24
|
-
|
25
|
-
validate_date if date
|
26
|
-
validate_severity if severity
|
27
|
-
validate_status if status
|
28
|
-
validate_tlp if tlp
|
29
|
-
validate_artifacts if artifacts
|
30
|
-
end
|
31
|
-
|
32
|
-
def payload
|
33
|
-
{
|
34
|
-
title: title,
|
35
|
-
description: description,
|
36
|
-
severity: severity,
|
37
|
-
date: date,
|
38
|
-
tags: tags,
|
39
|
-
tlp: tlp,
|
40
|
-
status: status,
|
41
|
-
type: type,
|
42
|
-
source: source,
|
43
|
-
sourceRef: source_ref,
|
44
|
-
artifacts: artifacts&.map(&:payload),
|
45
|
-
follow: follow
|
46
|
-
}.compact
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def validate_date
|
52
|
-
DateTime.parse(date)
|
53
|
-
true
|
54
|
-
rescue ArgumentError => _e
|
55
|
-
raise ArgumentError, "date should be Date format"
|
56
|
-
end
|
57
|
-
|
58
|
-
def validate_artifacts
|
59
|
-
artifacts.each(&:validate_for_creation)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Hachi
|
4
|
-
module Models
|
5
|
-
class Artifact < Base
|
6
|
-
DATA_TYPES = %w(filename file fqdn hash uri_path ip domain mail autonomous-system registry mail_subject regexp user-agent other url).freeze
|
7
|
-
|
8
|
-
attr_reader :data, :data_type, :message, :tlp, :tags
|
9
|
-
|
10
|
-
def initialize(data:, data_type:, message: nil, tlp: nil, tags: nil)
|
11
|
-
@data = data
|
12
|
-
@data_type = data_type
|
13
|
-
@message = message
|
14
|
-
@tlp = tlp
|
15
|
-
@tags = tags
|
16
|
-
|
17
|
-
raise(ArgumentError, "data is required") unless data
|
18
|
-
raise(ArgumentError, "data_type is required") unless data_type
|
19
|
-
raise(ArgumentError, "invalid data type") unless DATA_TYPES.include?(data_type)
|
20
|
-
|
21
|
-
validate_tags if tags
|
22
|
-
validate_tlp if tlp
|
23
|
-
end
|
24
|
-
|
25
|
-
def payload
|
26
|
-
{
|
27
|
-
data: data,
|
28
|
-
dataType: data_type,
|
29
|
-
message: message,
|
30
|
-
tlp: tlp,
|
31
|
-
tags: tags
|
32
|
-
}.compact
|
33
|
-
end
|
34
|
-
|
35
|
-
def validate_for_creation
|
36
|
-
raise(ArgumentError, "message or tags is requried for artifact creation") unless message || tags
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|