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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a88c7c477df9e4dbd8566ff3464424dbd994f9d976f9e235b6c1244200d32fd7
|
4
|
+
data.tar.gz: 1729ececbdb34f98abff15b7d80c189729d10d840f199876c87dc8eb22411581
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40517bf2830268e88af14dc70ffc1af9f1e7c32d509e53883b6e125b48b7e689b81f628eb6225f2b76c517479ab19efb721ccea0b24b8bf9df11b598796aeb4d
|
7
|
+
data.tar.gz: e334655c99088a1038618b85a03f068fe3c459bd25f5eb179cc6a69bfb654aed185893e0d139ea270854cb87e80e6c62120c70a8f7e1a2f79e4325207b66c0be
|
data/.github/workflows/test.yml
CHANGED
@@ -4,23 +4,20 @@ on: [pull_request]
|
|
4
4
|
|
5
5
|
jobs:
|
6
6
|
build:
|
7
|
-
|
8
7
|
runs-on: ubuntu-latest
|
9
8
|
|
10
9
|
strategy:
|
11
10
|
fail-fast: false
|
12
11
|
matrix:
|
13
|
-
ruby: [2.7,
|
12
|
+
ruby: [2.7, "3.0", 3.1]
|
14
13
|
|
15
14
|
steps:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
bundle install
|
26
|
-
bundle exec rake
|
15
|
+
- uses: actions/checkout@v3
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
20
|
+
bundler-cache: true
|
21
|
+
- name: Test with Rake
|
22
|
+
run: |
|
23
|
+
bundle exec rake
|
data/.gitignore
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
/tmp/
|
12
12
|
|
13
13
|
# Used by dotenv library to load environment variables.
|
14
|
-
|
14
|
+
.env
|
15
15
|
|
16
16
|
## Specific to RubyMotion:
|
17
17
|
.dat*
|
@@ -51,3 +51,7 @@ Gemfile.lock
|
|
51
51
|
|
52
52
|
# RSpec
|
53
53
|
.rspec_status
|
54
|
+
|
55
|
+
# Docker
|
56
|
+
Dockerfile
|
57
|
+
docker-compose.yml
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
Hachi(`蜂`) is a dead simple [TheHive](https://github.com/TheHive-Project/TheHive) API wrapper for Ruby.
|
9
9
|
|
10
|
-
**Note**: This library supports TheHive v4.
|
10
|
+
**Note**: This library supports TheHive v4 & v5.
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
@@ -17,95 +17,21 @@ gem install hachi
|
|
17
17
|
|
18
18
|
## Usage
|
19
19
|
|
20
|
+
Hachi tries to load API settings from `ENV` by default. Or you can set them manually.
|
21
|
+
|
22
|
+
| Name | Default | Desc. |
|
23
|
+
|--------------|-----------------------------|-------------------------------------------------|
|
24
|
+
| api_key | ENV["THEHIVE_API_KEY"] | TheHive API key |
|
25
|
+
| api_endpoint | ENV["THEHIVE_API_ENDPOINT"] | TheHive API endpoint |
|
26
|
+
| api_version | ENV["THEHIVE_API_VERSION"] | TheHive API version (`nil` for v4, `v1` for v5) |
|
27
|
+
|
20
28
|
```ruby
|
21
29
|
require "hachi"
|
22
30
|
|
23
|
-
# when given nothing, it tries to load your API key from ENV
|
31
|
+
# when given nothing, it tries to load your API key from ENV
|
24
32
|
api = Hachi::API.new
|
25
33
|
# or you can set them manually
|
26
34
|
api = Hachi::API.new(api_endpoint: "http://your_api_endpoint", api_key: "yoru_api_key")
|
27
|
-
|
28
|
-
# list alerts
|
29
|
-
api.alert.list
|
30
|
-
|
31
|
-
# search artifacts
|
32
|
-
query = { "_and": [{ "_or": [{ "_field": "data", "_value": "1.1.1.1" }, { "_field": "data", "_value": "example.com" }] }] }
|
33
|
-
api.artifact.search(query)
|
34
|
-
```
|
35
|
-
|
36
|
-
See `samples` for more.
|
37
|
-
|
38
|
-
## Implemented methods
|
39
|
-
|
40
|
-
### Alert
|
41
|
-
|
42
|
-
| HTTP Method | URI | Action | API method |
|
43
|
-
|-------------|-----------------------------------|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
44
|
-
| GET | /api/alert | List alerts | `#api.alert.list` |
|
45
|
-
| POST | /api/alert/_search | Find alerts | `#api.alert.search(query, range: "all")` |
|
46
|
-
| PATCH | /api/alert/_bulk | Update alerts in bulk | N/A |
|
47
|
-
| POST | /api/alert/_stats | Compute stats on alerts | N/A |
|
48
|
-
| POST | /api/alert | Create an alert | `#api.alert.create(title:, description:, severity: nil, date: nil, tags: nil, tlp: nil, status: nil, type:, source:, source_ref: nil, artifacts: nil, follow: nil)` |
|
49
|
-
| GET | /api/alert/:alertId | Get an alert | `#api.alert.get_by_id(id)` |
|
50
|
-
| PATCH | /api/alert/:alertId | Update an alert | `#api.alert.update(id, title:, description:, severity: nil, tags: nil, tlp: nil, artifacts: nil)` |
|
51
|
-
| DELETE | /api/alert/:alertId | Delete an alert | `#api.alert.delete_by_id(id)` |
|
52
|
-
| POST | /api/alert/:alertId/markAsRead | Mark an alert as read | `#api.alert.mark_as_read(id)` |
|
53
|
-
| POST | /api/alert/:alertId/markAsUnread | Mark an alert as unread | `#api.alert.mark_as_unread(id)` |
|
54
|
-
| POST | /api/alert/:alertId/createCase | Create a case from an alert | `#api.alert.promote_to_case(id)` |
|
55
|
-
| POST | /api/alert/:alertId/follow | Follow an alert | N/A |
|
56
|
-
| POST | /api/alert/:alertId/unfollow | Unfollow an alert | N/A |
|
57
|
-
| POST | /api/alert/:alertId/merge/:caseId | Merge an alert in a case | `#api.alert.merge_into_case(*ids, case_id)` |
|
58
|
-
|
59
|
-
### Artifact(Observable)
|
60
|
-
|
61
|
-
| HTTP Method | URI | Action | API method |
|
62
|
-
|-------------|----------------------------------------|---------------------------------|---------------------------------------------------------------------------------------|
|
63
|
-
| POST | /api/case/artifact/_search | Find observables | `#api.artifact.search(query, range: "all")` |
|
64
|
-
| POST | /api/case/artifact/_stats | Compute stats on observables | N/A |
|
65
|
-
| POST | /api/case/:caseId/artifact | Create an observable | `#api.artifact.create(case_id, data:, data_type:, message: nil, tlp: nil, tags: nil)` |
|
66
|
-
| GET | /api/case/artifact/:artifactId | Get an observable | `#api.artifact.get_by_id(id)` |
|
67
|
-
| DELETE | /api/case/artifact/:artifactId | Remove an observable | `#api.artifact.delete_by_id(id)` |
|
68
|
-
| PATCH | /api/case/artifact/:artifactId | Update an observable | N/A |
|
69
|
-
| GET | /api/case/artifact/:artifactId/similar | Get list of similar observables | `#api.artifact.similar(id)` |
|
70
|
-
| PATCH | /api/case/artifact/_bulk | Update observables in bulk | N/A |
|
71
|
-
|
72
|
-
### Case
|
73
|
-
|
74
|
-
| HTTP Method | URI | Action | API method |
|
75
|
-
|-------------|------------------------------------|---------------------------------------|----------------------------------------------------------------------------------------------------------------------|
|
76
|
-
| GET | /api/case | List cases | `#api.case.list` |
|
77
|
-
| POST | /api/case/_search | Find cases | `#api.case.search(query, range: "all")` |
|
78
|
-
| PATCH | /api/case/_bulk | Update cases in bulk | N/A |
|
79
|
-
| POST | /api/case/_stats | Compute stats on cases | N/A |
|
80
|
-
| POST | /api/case | Create a case | `#api.case.create(title:, description:, severity: nil, start_date: nil, owner: nil, flag: nil, tlp: nil, tags: nil)` |
|
81
|
-
| GET | /api/case/:caseId | Get a case | `#api.case.get_by_id(id)` |
|
82
|
-
| PATCH | /api/case/:caseId | Update a case | N/A |
|
83
|
-
| DELETE | /api/case/:caseId | Remove a case | `#api.case.delete_by_id(id)` |
|
84
|
-
| GET | /api/case/:caseId/links | Get list of cases linked to this case | `#api.case.links(id)` |
|
85
|
-
| POST | /api/case/:caseId1/_merge/:caseId2 | Merge two cases | `#api.case.merge(id1, id2)` |
|
86
|
-
|
87
|
-
### User
|
88
|
-
|
89
|
-
| HTTP Method | URI | Action | API method |
|
90
|
-
|-------------|-----------------------------------|---------------------|------------------------------------------------------|
|
91
|
-
| GET | /api/logout | Logout | N/A |
|
92
|
-
| POST | /api/login | User login | N/A |
|
93
|
-
| GET | /api/user/current | Get current user | `#api.user.current` |
|
94
|
-
| POST | /api/user/_search | Find user | N/A |
|
95
|
-
| POST | /api/user | Create a user | `#api.user.create(login:, name:, roles:, password:)` |
|
96
|
-
| GET | /api/user/:userId | Get a user | `#api.user.get_by_id(id)` |
|
97
|
-
| DELETE | /api/user/:userId | Delete a case | `#api.user.delete_by_id(id)` |
|
98
|
-
| PATCH | /api/user/:userId | Update user details | N/A |
|
99
|
-
| POST | /api/user/:userId/password/set | Set password | N/A |
|
100
|
-
| POST | /api/user/:userId/password/change | Change password | N/A |
|
101
|
-
|
102
|
-
|
103
|
-
## How to interact with unimplemented API endpoints
|
104
|
-
|
105
|
-
`Hachi::API` exposes `get`, `post`, `delete` and `patch` methods. You can interact with the API endpoints via the methods.
|
106
|
-
|
107
|
-
```ruby
|
108
|
-
alerts = api.get("/api/alert" ) { |json| json }
|
109
35
|
```
|
110
36
|
|
111
37
|
## License
|
data/hachi.gemspec
CHANGED
@@ -24,10 +24,12 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
-
spec.add_development_dependency "bundler", "~> 2.
|
28
|
-
spec.add_development_dependency "
|
27
|
+
spec.add_development_dependency "bundler", "~> 2.3"
|
28
|
+
spec.add_development_dependency "coveralls_reborn", "~> 0.24"
|
29
|
+
spec.add_development_dependency "dotenv", "~> 2.7"
|
29
30
|
spec.add_development_dependency "rake", "~> 13.0"
|
30
|
-
spec.add_development_dependency "rspec", "~> 3.
|
31
|
-
spec.add_development_dependency "
|
32
|
-
spec.add_development_dependency "
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.11"
|
32
|
+
spec.add_development_dependency "simplecov-lcov", "~> 0.8.0"
|
33
|
+
spec.add_development_dependency "vcr", "~> 6.1"
|
34
|
+
spec.add_development_dependency "webmock", "~> 3.14"
|
33
35
|
end
|
data/lib/hachi/api.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "forwardable"
|
4
4
|
|
5
5
|
module Hachi
|
6
6
|
class API
|
@@ -12,20 +12,26 @@ module Hachi
|
|
12
12
|
# @return [String] TheHive API key
|
13
13
|
attr_reader :api_key
|
14
14
|
|
15
|
+
# @return [String, nil] TheHive API version
|
16
|
+
attr_reader :api_version
|
17
|
+
|
15
18
|
#
|
16
19
|
# @param [String, nil] api_endpoint TheHive API endpoint
|
17
20
|
# @param [String, nil] api_key TheHive API key
|
21
|
+
# @param [String, nil] api_version TheHive API version
|
18
22
|
#
|
19
23
|
# @raise [ArgumentError] When given or an empty endpoint or key
|
20
24
|
#
|
21
|
-
def initialize(api_endpoint: ENV
|
25
|
+
def initialize(api_endpoint: ENV.fetch("THEHIVE_API_ENDPOINT", nil), api_key: ENV.fetch("THEHIVE_API_KEY", nil), api_version: ENV.fetch("THEHIVE_API_VERSION", nil))
|
22
26
|
@api_endpoint = api_endpoint
|
23
27
|
raise ArgumentError, "api_endpoint argument is required" unless api_endpoint
|
24
28
|
|
25
29
|
@api_key = api_key
|
26
30
|
raise ArgumentError, "api_key argument is required" unless api_key
|
27
31
|
|
28
|
-
@
|
32
|
+
@api_version = api_version
|
33
|
+
|
34
|
+
@base = Clients::Base.new(api_endpoint: api_endpoint, api_key: api_key, api_version: api_version)
|
29
35
|
end
|
30
36
|
|
31
37
|
def_delegators :@base, :get, :post, :delete, :push
|
@@ -36,7 +42,7 @@ module Hachi
|
|
36
42
|
# @return [Clients::Alert]
|
37
43
|
#
|
38
44
|
def alert
|
39
|
-
@alert ||= Clients::Alert.new(api_endpoint: api_endpoint, api_key: api_key)
|
45
|
+
@alert ||= Clients::Alert.new(api_endpoint: api_endpoint, api_key: api_key, api_version: api_version)
|
40
46
|
end
|
41
47
|
|
42
48
|
#
|
@@ -45,7 +51,7 @@ module Hachi
|
|
45
51
|
# @return [Clients::Artifact]
|
46
52
|
#
|
47
53
|
def artifact
|
48
|
-
@artifact ||= Clients::Artifact.new(api_endpoint: api_endpoint, api_key: api_key)
|
54
|
+
@artifact ||= Clients::Artifact.new(api_endpoint: api_endpoint, api_key: api_key, api_version: api_version)
|
49
55
|
end
|
50
56
|
|
51
57
|
#
|
@@ -54,7 +60,7 @@ module Hachi
|
|
54
60
|
# @return [Clients::Case]
|
55
61
|
#
|
56
62
|
def case
|
57
|
-
@case ||= Clients::Case.new(api_endpoint: api_endpoint, api_key: api_key)
|
63
|
+
@case ||= Clients::Case.new(api_endpoint: api_endpoint, api_key: api_key, api_version: api_version)
|
58
64
|
end
|
59
65
|
|
60
66
|
#
|
@@ -63,7 +69,25 @@ module Hachi
|
|
63
69
|
# @return [Clients::User]
|
64
70
|
#
|
65
71
|
def user
|
66
|
-
@user ||= Clients::User.new(api_endpoint: api_endpoint, api_key: api_key)
|
72
|
+
@user ||= Clients::User.new(api_endpoint: api_endpoint, api_key: api_key, api_version: api_version)
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Observable API endpoint client
|
77
|
+
#
|
78
|
+
# @return [Clients::Observable]
|
79
|
+
#
|
80
|
+
def observable
|
81
|
+
@observable ||= Clients::Observable.new(api_endpoint: api_endpoint, api_key: api_key, api_version: api_version)
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Query API endpoint client
|
86
|
+
#
|
87
|
+
# @return [Clients::Query]
|
88
|
+
#
|
89
|
+
def query
|
90
|
+
@query ||= Clients::Query.new(api_endpoint: api_endpoint, api_key: api_key, api_version: api_version)
|
67
91
|
end
|
68
92
|
end
|
69
93
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# forked from https://github.com/technicalpanda/awrence
|
4
|
+
module Hachi
|
5
|
+
module Awrence
|
6
|
+
module Methods
|
7
|
+
# Recursively converts Rubyish snake_case hash keys to camelBack JSON-style
|
8
|
+
# hash keys suitable for use with a JSON API.
|
9
|
+
#
|
10
|
+
def to_camelback_keys(value = self)
|
11
|
+
process_value(:to_camelback_keys, value, first_upper: false)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Recursively converts Rubyish snake_case hash keys to CamelCase JSON-style
|
15
|
+
# hash keys suitable for use with a JSON API.
|
16
|
+
#
|
17
|
+
def to_camel_keys(value = self)
|
18
|
+
process_value(:to_camel_keys, value, first_upper: true)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def camelize_key(key, first_upper: true)
|
24
|
+
case key
|
25
|
+
when Symbol
|
26
|
+
camelize(key.to_s, first_upper: first_upper).to_sym
|
27
|
+
when String
|
28
|
+
camelize(key, first_upper: first_upper)
|
29
|
+
else
|
30
|
+
key # Awrence can't camelize anything except strings and symbols
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def camelize(snake_word, first_upper: true)
|
35
|
+
return snake_word if snake_word.start_with? "_"
|
36
|
+
|
37
|
+
if first_upper
|
38
|
+
str = snake_word.to_s
|
39
|
+
str = gsubbed(str, /(?:^|_)([^_\s]+)/)
|
40
|
+
gsubbed(str, %r{/([^/]*)}, "::")
|
41
|
+
else
|
42
|
+
parts = snake_word.split("_", 2)
|
43
|
+
parts[0] << camelize(parts[1]) if parts.size > 1
|
44
|
+
parts[0] || ""
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def gsubbed(str, pattern, extra = "")
|
49
|
+
str.gsub(pattern) do
|
50
|
+
extra + (Hachi::Awrence.acronyms[Regexp.last_match(1)] || Regexp.last_match(1).capitalize)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_value(method, value, first_upper: true)
|
55
|
+
case value
|
56
|
+
when Array
|
57
|
+
value.map { |v| send(method, v) }
|
58
|
+
when Hash
|
59
|
+
value.to_h { |k, v| [camelize_key(k, first_upper: first_upper), send(method, v)] }
|
60
|
+
else
|
61
|
+
value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/hachi/clients/alert.rb
CHANGED
@@ -6,15 +6,6 @@ require "securerandom"
|
|
6
6
|
module Hachi
|
7
7
|
module Clients
|
8
8
|
class Alert < Base
|
9
|
-
#
|
10
|
-
# List alerts
|
11
|
-
#
|
12
|
-
# @return [Array]
|
13
|
-
#
|
14
|
-
def list
|
15
|
-
get("/api/alert") { |json| json }
|
16
|
-
end
|
17
|
-
|
18
9
|
#
|
19
10
|
# Get an alert
|
20
11
|
#
|
@@ -23,7 +14,7 @@ module Hachi
|
|
23
14
|
# @return [Hash]
|
24
15
|
#
|
25
16
|
def get_by_id(id)
|
26
|
-
get("/
|
17
|
+
get("/alert/#{id}") { |json| json }
|
27
18
|
end
|
28
19
|
|
29
20
|
#
|
@@ -34,130 +25,29 @@ module Hachi
|
|
34
25
|
# @return [String]
|
35
26
|
#
|
36
27
|
def delete_by_id(id)
|
37
|
-
delete("/
|
28
|
+
delete("/alert/#{id}") { |json| json }
|
38
29
|
end
|
39
30
|
|
40
31
|
#
|
41
32
|
# Create an alert
|
42
33
|
#
|
43
|
-
# @param [
|
44
|
-
# @param [String] description
|
45
|
-
# @param [String, nil] severity
|
46
|
-
# @param [String, nil] date
|
47
|
-
# @param [String, nil] tags
|
48
|
-
# @param [String, nil] tlp
|
49
|
-
# @param [String, nil] status
|
50
|
-
# @param [String, nil] type
|
51
|
-
# @param [String, nil] source
|
52
|
-
# @param [String, nil] source_ref
|
53
|
-
# @param [String, nil] artifacts
|
54
|
-
# @param [String, nil] follow
|
55
|
-
#
|
56
|
-
# @return [Hash]
|
57
|
-
#
|
58
|
-
def create(title:, description:, type:, source:, severity: nil, date: nil, tags: nil, tlp: nil, status: nil, source_ref: nil, artifacts: nil, follow: nil)
|
59
|
-
alert = Models::Alert.new(
|
60
|
-
title: title,
|
61
|
-
description: description,
|
62
|
-
severity: severity,
|
63
|
-
date: date,
|
64
|
-
tags: tags,
|
65
|
-
tlp: tlp,
|
66
|
-
status: status,
|
67
|
-
type: type,
|
68
|
-
source: source,
|
69
|
-
source_ref: source_ref,
|
70
|
-
artifacts: artifacts,
|
71
|
-
follow: follow,
|
72
|
-
)
|
73
|
-
post("/api/alert", json: alert.payload) { |json| json }
|
74
|
-
end
|
75
|
-
|
76
|
-
#
|
77
|
-
# Find alerts
|
78
|
-
#
|
79
|
-
# @param [Hash] query
|
80
|
-
# @param [String] range
|
81
|
-
# @param [String, nil] sort
|
82
|
-
#
|
83
|
-
# @return [Array]
|
84
|
-
#
|
85
|
-
def search(query, range: "all", sort: nil)
|
86
|
-
_search("/api/alert/_search", query: query, range: range, sort: sort) { |json| json }
|
87
|
-
end
|
88
|
-
|
89
|
-
#
|
90
|
-
# Mark an alert as read
|
91
|
-
#
|
92
|
-
# @param [String] id Alert ID
|
93
|
-
#
|
94
|
-
# @return [Hash]
|
95
|
-
#
|
96
|
-
def mark_as_read(id)
|
97
|
-
post("/api/alert/#{id}/markAsRead") { |json| json }
|
98
|
-
end
|
99
|
-
|
100
|
-
#
|
101
|
-
# Mark an alert as unread
|
102
|
-
#
|
103
|
-
# @param [String] id Alert ID
|
104
|
-
#
|
105
|
-
# @return [Hash] hash
|
106
|
-
#
|
107
|
-
def mark_as_unread(id)
|
108
|
-
post("/api/alert/#{id}/markAsUnread") { |json| json }
|
109
|
-
end
|
110
|
-
|
111
|
-
#
|
112
|
-
# Create a case from an alert
|
113
|
-
#
|
114
|
-
# @param [String] id Alert ID
|
115
|
-
#
|
116
|
-
# @return [Hash]
|
117
|
-
#
|
118
|
-
def promote_to_case(id)
|
119
|
-
post("/api/alert/#{id}/createCase") { |json| json }
|
120
|
-
end
|
121
|
-
|
122
|
-
#
|
123
|
-
# Merge an alert / alerts in a case
|
124
|
-
#
|
125
|
-
# @param [String, Array] *ids Alert ID(s)
|
126
|
-
# @param [String] case_id Case ID
|
34
|
+
# @param [Hash] payload
|
127
35
|
#
|
128
36
|
# @return [Hash]
|
129
37
|
#
|
130
|
-
def
|
131
|
-
|
132
|
-
alertIds: ids.flatten,
|
133
|
-
caseId: case_id
|
134
|
-
}
|
135
|
-
post("/api/alert/merge/_bulk", json: params) { |json| json }
|
38
|
+
def create(**payload)
|
39
|
+
post("/alert", json: payload) { |json| json }
|
136
40
|
end
|
137
41
|
|
138
|
-
#
|
139
42
|
# Update an alert
|
140
43
|
#
|
141
|
-
# @param [String
|
142
|
-
# @param [
|
143
|
-
# @param [String, nil] description
|
144
|
-
# @param [String, nil] severity
|
145
|
-
# @param [String, nil] tags
|
146
|
-
# @param [String, nil] tlp
|
147
|
-
# @param [String, nil] artifacts
|
44
|
+
# @param [String] id
|
45
|
+
# @param [Hash] payload
|
148
46
|
#
|
149
47
|
# @return [Hash]
|
150
48
|
#
|
151
|
-
def update(id,
|
152
|
-
|
153
|
-
title: title,
|
154
|
-
description: description,
|
155
|
-
severity: severity,
|
156
|
-
tags: tags,
|
157
|
-
tlp: tlp,
|
158
|
-
artifacts: artifacts,
|
159
|
-
}.compact
|
160
|
-
patch("/api/alert/#{id}", json: attributes) { |json| json }
|
49
|
+
def update(id, **payload)
|
50
|
+
patch("/alert/#{id}", json: payload) { |json| json }
|
161
51
|
end
|
162
52
|
end
|
163
53
|
end
|
@@ -7,24 +7,12 @@ module Hachi
|
|
7
7
|
# Create an artifact
|
8
8
|
#
|
9
9
|
# @param [String] case_id Artifact ID
|
10
|
-
# @param [
|
11
|
-
# @param [String] data_type
|
12
|
-
# @param [String, nil] message
|
13
|
-
# @param [Integer, nil] tlp
|
14
|
-
# @param [Array<String>, nil] tags
|
10
|
+
# @param [Hash] payload
|
15
11
|
#
|
16
12
|
# @return [Hash]
|
17
13
|
#
|
18
|
-
def create(case_id,
|
19
|
-
artifact
|
20
|
-
data: data,
|
21
|
-
data_type: data_type,
|
22
|
-
message: message,
|
23
|
-
tlp: tlp,
|
24
|
-
tags: tags,
|
25
|
-
)
|
26
|
-
|
27
|
-
post("/api/case/#{case_id}/artifact", json: artifact.payload) { |json| json }
|
14
|
+
def create(case_id, **payload)
|
15
|
+
post("/api/case/#{case_id}/artifact", json: payload) { |json| json }
|
28
16
|
end
|
29
17
|
|
30
18
|
#
|
@@ -48,29 +36,6 @@ module Hachi
|
|
48
36
|
def delete_by_id(id)
|
49
37
|
delete("/api/case/artifact/#{id}") { |json| json }
|
50
38
|
end
|
51
|
-
|
52
|
-
#
|
53
|
-
# Find artifacts
|
54
|
-
#
|
55
|
-
# @param [Hash] query
|
56
|
-
# @param [String] range
|
57
|
-
#
|
58
|
-
# @return [Array]
|
59
|
-
#
|
60
|
-
def search(query, range: "all")
|
61
|
-
_search("/api/case/artifact/_search", query: query, range: range) { |json| json }
|
62
|
-
end
|
63
|
-
|
64
|
-
#
|
65
|
-
# Get list of similar observables
|
66
|
-
#
|
67
|
-
# @param [String] id Artifact ID
|
68
|
-
#
|
69
|
-
# @return [Array]
|
70
|
-
#
|
71
|
-
def similar(id)
|
72
|
-
get("/api/case/artifact/#{id}/similar") { |json| json }
|
73
|
-
end
|
74
39
|
end
|
75
40
|
end
|
76
41
|
end
|