hachi 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|