hachi 0.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,18 +7,83 @@ require "uri"
7
7
  module Hachi
8
8
  module Clients
9
9
  class Base
10
+ # @return [String]
10
11
  attr_reader :api_endpoint
12
+
13
+ # @return [String]
11
14
  attr_reader :api_key
12
15
 
13
- def initialize(api_endpoint:, api_key:)
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:)
14
22
  @api_endpoint = URI(api_endpoint)
15
23
  @api_key = api_key
24
+ @api_version = api_version
25
+ end
26
+
27
+ def get(path, params: {}, &block)
28
+ url = url_for(path)
29
+ url.query = URI.encode_www_form(params) unless params.empty?
30
+
31
+ get = Net::HTTP::Get.new(url)
32
+ get.add_field "Authorization", "Bearer #{api_key}"
33
+ request(get, &block)
34
+ end
35
+
36
+ def post(path, params: {}, json: {}, &block)
37
+ url = url_for(path)
38
+ url.query = URI.encode_www_form(params) unless params.empty?
39
+
40
+ json = to_camelback_keys(json.compact) if json.is_a?(Hash)
41
+
42
+ post = Net::HTTP::Post.new(url)
43
+ post.body = json.is_a?(Hash) ? json.to_json : json.to_s
44
+
45
+ post.add_field "Content-Type", "application/json"
46
+ post.add_field "Authorization", "Bearer #{api_key}"
47
+
48
+ request(post, &block)
49
+ end
50
+
51
+ def delete(path, params: {}, json: {}, &block)
52
+ url = url_for(path)
53
+ url.query = URI.encode_www_form(params) unless params.empty?
54
+
55
+ json = to_camelback_keys(json.compact) if json.is_a?(Hash)
56
+
57
+ delete = Net::HTTP::Delete.new(url)
58
+ delete.body = json.is_a?(Hash) ? json.to_json : json.to_s
59
+
60
+ delete.add_field "Authorization", "Bearer #{api_key}"
61
+ request(delete, &block)
62
+ end
63
+
64
+ def patch(path, params: {}, json: {}, &block)
65
+ url = url_for(path)
66
+ url.query = URI.encode_www_form(params) unless params.empty?
67
+
68
+ json = to_camelback_keys(json.compact) if json.is_a?(Hash)
69
+
70
+ patch = Net::HTTP::Patch.new(url)
71
+ patch.body = json.is_a?(Hash) ? json.to_json : json.to_s
72
+
73
+ patch.add_field "Content-Type", "application/json"
74
+ patch.add_field "Authorization", "Bearer #{api_key}"
75
+
76
+ request(patch, &block)
16
77
  end
17
78
 
18
79
  private
19
80
 
20
81
  def base_url
21
- "#{api_endpoint.scheme}://#{api_endpoint.hostname}:#{api_endpoint.port}"
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
22
87
  end
23
88
 
24
89
  def url_for(path)
@@ -28,13 +93,13 @@ module Hachi
28
93
  def https_options
29
94
  return nil if api_endpoint.scheme != "https"
30
95
 
31
- if proxy = ENV["HTTPS_PROXY"] || ENV["https_proxy"]
96
+ if proxy = ENV.fetch("HTTPS_PROXY") { ENV.fetch("https_proxy", nil) }
32
97
  uri = URI(proxy)
33
98
  {
34
99
  proxy_address: uri.hostname,
35
100
  proxy_port: uri.port,
36
101
  proxy_from_env: false,
37
- use_ssl: true,
102
+ use_ssl: true
38
103
  }
39
104
  else
40
105
  { use_ssl: true }
@@ -42,12 +107,12 @@ module Hachi
42
107
  end
43
108
 
44
109
  def http_options
45
- if proxy = ENV["HTTP_PROXY"] || ENV["http_proxy"]
110
+ if proxy = ENV.fetch("HTTP_PROXY") { ENV.fetch("http_proxy", nil) }
46
111
  uri = URI(proxy)
47
112
  {
48
113
  proxy_address: uri.hostname,
49
114
  proxy_port: uri.port,
50
- proxy_from_env: false,
115
+ proxy_from_env: false
51
116
  }
52
117
  else
53
118
  {}
@@ -74,107 +139,8 @@ module Hachi
74
139
  end
75
140
  end
76
141
 
77
- def get(path, params = {}, &block)
78
- url = url_for(path)
79
- url.query = URI.encode_www_form(params) unless params.empty?
80
-
81
- get = Net::HTTP::Get.new(url)
82
- get.add_field "Authorization", "Bearer #{api_key}"
83
- request(get, &block)
84
- end
85
-
86
- def post(path, params = {}, &block)
87
- url = url_for(path)
88
-
89
- post = Net::HTTP::Post.new(url)
90
- post.body = params.is_a?(Hash) ? params.to_json : params.to_s
91
-
92
- post.add_field "Content-Type", "application/json"
93
- post.add_field "Authorization", "Bearer #{api_key}"
94
-
95
- request(post, &block)
96
- end
97
-
98
- def delete(path, params = {}, &block)
99
- url = url_for(path)
100
- url.query = URI.encode_www_form(params) unless params.empty?
101
-
102
- delete = Net::HTTP::Delete.new(url)
103
- delete.add_field "Authorization", "Bearer #{api_key}"
104
- request(delete, &block)
105
- end
106
-
107
- def patch(path, params = {}, &block)
108
- url = url_for(path)
109
-
110
- patch = Net::HTTP::Patch.new(url)
111
- patch.body = params.is_a?(Hash) ? params.to_json : params.to_s
112
-
113
- patch.add_field "Content-Type", "application/json"
114
- patch.add_field "Authorization", "Bearer #{api_key}"
115
-
116
- request(patch, &block)
117
- end
118
-
119
- def validate_range(range)
120
- return true if range == "all"
121
- raise ArgumentError, "range should be 'all' or `from-to`" unless range.match?(/(\d+)-(\d+)/)
122
-
123
- from, to = range.split("-").map(&:to_i)
124
- return true if from < to
125
-
126
- raise ArgumentError, "from should be smaller than to"
127
- end
128
-
129
- def _search(path, attributes:, range: "all", sort: nil)
130
- validate_range range
131
-
132
- attributes = normalize_attributes(attributes)
133
- conditions = attributes.map do |key, value|
134
- if key == :data && value.is_a?(Array)
135
- { _or: decompose_data(value) }
136
- else
137
- { _string: "#{key}:\"#{value}\"" }
138
- end
139
- end
140
-
141
- default_conditions = {
142
- _and: [
143
- { _not: { status: "Deleted" } },
144
- { _not: { _in: { _field: "_type", _values: ["dashboard", "data", "user", "analyzer", "caseTemplate", "reportTemplate", "action"] } } },
145
- ],
146
- }
147
-
148
- query = {
149
- _and: [conditions, default_conditions].flatten,
150
- }
151
-
152
- query_string = build_query_string(range: range, sort: sort)
153
-
154
- post("#{path}?#{query_string}", query: query) { |json| json }
155
- end
156
-
157
- def decompose_data(data)
158
- data.map do |elem|
159
- { _field: "data", _value: elem }
160
- end
161
- end
162
-
163
- def normalize_attributes(attributes)
164
- h = {}
165
- attributes.each do |key, value|
166
- h[camelize(key).to_sym] = value
167
- end
168
- h
169
- end
170
-
171
- def camelize(string)
172
- head, *others = string.to_s.split("_")
173
- [head, others.map(&:capitalize)].flatten.join
174
- end
175
-
176
142
  def build_query_string(params)
177
- URI.encode_www_form(params.reject { |_k, v| v.nil? })
143
+ URI.encode_www_form(params.compact)
178
144
  end
179
145
  end
180
146
  end
@@ -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("/api/case/#{id}") { |json| json }
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("/api/case/#{id}") { |json| json }
25
+ delete("/case/#{id}") { |json| json }
35
26
  end
36
27
 
37
28
  #
38
29
  # Create a case
39
30
  #
40
- # @param [String, nil] title
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", kase.payload) { |json| json }
64
- end
65
-
66
- #
67
- # Find cases
68
- #
69
- # @param [Hash] attributes
70
- # @param [String] range
71
- #
72
- # @return [Hash]
73
- #
74
- def search(attributes, range: "all")
75
- _search("/api/case/_search", attributes: attributes, 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 merge(id1, id2)
98
- post("/api/case/#{id1}/_merge/#{id2}") { |json| json }
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, nil] id
105
- # @param [String, nil] title
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, title: nil, description: nil, severity: nil, start_date: nil, owner: nil, flag: nil, tlp: nil, tags: nil, status: nil, resolution_status: nil, impact_status: nil, summary: nil, end_date: nil, metrics: nil, custom_fields: nil )
124
- attributes = {
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}", 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
@@ -9,7 +9,7 @@ module Hachi
9
9
  # @return [Hash]
10
10
  #
11
11
  def current
12
- get("/api/user/current") { |json| json }
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("/api/user/#{id}") { |json| json }
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("/api/user/#{id}") { |json| json }
34
+ delete("/user/#{id}") { |json| json }
35
35
  end
36
36
 
37
37
  #
38
38
  # Create a user
39
39
  #
40
- # @param [String] login
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(login:, name:, roles:, password:)
48
- user = Models::User.new(
49
- login: login,
50
- name: name,
51
- roles: roles,
52
- password: password
53
- )
54
-
55
- post("/api/user", 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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hachi
4
- VERSION = "0.3.1"
4
+ VERSION = "2.0.0"
5
5
  end
data/lib/hachi.rb CHANGED
@@ -2,20 +2,29 @@
2
2
 
3
3
  require "hachi/version"
4
4
 
5
- require "hachi/api"
5
+ require "hachi/awrence/methods"
6
6
 
7
- require "hachi/models/base"
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
data/renovate.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": [
3
+ "config:base"
4
+ ]
5
+ }