misp 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db847f1e32b2e0a1064180b310b087ade5c9d608282bcbeebc5403f02b0cb71d
4
- data.tar.gz: e1090389330d2de0bfd8b0c58cd0768f1a9bc58bb220d80c9d74aea6cb9ec738
3
+ metadata.gz: 3be99f0060b369edec33cbfd1f8451ecfdd1d3c4942091087473abdc96579fc8
4
+ data.tar.gz: eb6d2f9fe09fd030f6cf0f4e9f73e4b19d650809c3f0121c29b9de2b421fb97c
5
5
  SHA512:
6
- metadata.gz: a4b3e71c139193309e919b6dc344f4fb200521b07a90fd3e45384d272549632af96eec9852416fdc8ddbfda31c9675f5ab107ae4cb1b2ff61b98dbeba0979457
7
- data.tar.gz: 16b98a9dae45d273b70600565f8130d43d592e4097b517f49a69177c367a8c88a5841e4eb238a9629f9a45d1ca12ce7addfb5118c27f52d45a9c4a0ae3e56f61
6
+ metadata.gz: b0659e4345163616f8ad38fd43a391ab3f9921c0cf4d5e926ac74bda7b13762cbaca7f5518041e67795b9518c63a81945f503e54e25d4c8e37e14801e41a3335
7
+ data.tar.gz: 2e85ada078b9b82eb9221cec0d0b012d731c0dd082b147306f7c0b69a473aa583ac98153c882ba51e6a072fce26d348f607a1178515cca38395624d5db59d7e3
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # misp-rb
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/misp.svg)](https://badge.fury.io/rb/misp)
3
4
  [![Build Status](https://travis-ci.com/ninoseki/misp-rb.svg?branch=master)](https://travis-ci.com/ninoseki/misp-rb)
4
5
  [![Coverage Status](https://coveralls.io/repos/github/ninoseki/misp-rb/badge.svg?branch=master)](https://coveralls.io/github/ninoseki/misp-rb?branch=master)
5
6
  [![CodeFactor](https://www.codefactor.io/repository/github/ninoseki/misp-rb/badge)](https://www.codefactor.io/repository/github/ninoseki/misp-rb)
@@ -20,8 +21,8 @@ gem install misp
20
21
 
21
22
  By default, it tries to load configurations from environmental variables:
22
23
 
23
- - MISP API endpoint from ENV["MISP_API_ENDPOINT"]
24
- - MISP API key from ENV["MISP_API_KEY"]
24
+ - `MISP_API_ENDPOINT`: MISP API endpoint (e.g. https://misppriv.circl.lu)
25
+ - `MISP_API_KEY`: MISP API key
25
26
 
26
27
  Also, you can configure them manually.
27
28
 
@@ -60,7 +61,7 @@ event.update
60
61
  event = MISP::Event.get(17)
61
62
  event.add_attribute(value: "8.8.8.8", type: "ip-dst")
62
63
  # or
63
- attribute = MISP::Attribute(value: "1.1.1.1", type: "ip-dst")
64
+ attribute = MISP::Attribute.new(value: "1.1.1.1", type: "ip-dst")
64
65
  event.add_attribute attribute
65
66
  event.update
66
67
  ```
@@ -109,6 +110,14 @@ event.tags << MISP::Tag.new(name: "my event-level tag")
109
110
  event.create
110
111
  ```
111
112
 
113
+ ### Search for events / attributes
114
+
115
+ ```ruby
116
+ events = MISP::Event.search(info: "test")
117
+
118
+ attributes = MISP::Attribute.search(type: "ip-dst")
119
+ ```
120
+
112
121
  ## Acknowledgement
113
122
 
114
123
  The implementation design of this gem is highly influenced by [FloatingGhost/mispex](https://github.com/FloatingGhost/mispex).
@@ -2,23 +2,40 @@
2
2
 
3
3
  module MISP
4
4
  class Attribute < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_accessor :type
9
+ # @return [String]
7
10
  attr_accessor :category
11
+ # @return [Boolean]
8
12
  attr_accessor :to_ids
13
+ # @return [String]
9
14
  attr_reader :uuid
15
+ # @return [String]
10
16
  attr_reader :event_id
17
+ # @return [String]
11
18
  attr_accessor :distribution
19
+ # @return [String]
12
20
  attr_accessor :timestamp
21
+ # @return [String]
13
22
  attr_accessor :comment
23
+ # @return [String]
14
24
  attr_accessor :sharing_group_id
25
+ # @return [Boolean]
15
26
  attr_accessor :deleted
27
+ # @return [Boolean]
16
28
  attr_accessor :disable_correlation
29
+ # @return [String]
17
30
  attr_accessor :value
31
+ # @return [String]
18
32
  attr_accessor :data
19
33
 
34
+ # @return [Array<MISP::SharingGroup>]
20
35
  attr_accessor :sharing_groups
36
+ # @return [Array<MISP::Attribute>]
21
37
  attr_accessor :shadow_attributes
38
+ # @return [Array<MISP::Tag>]
22
39
  attr_accessor :tags
23
40
 
24
41
  def initialize(**attributes)
@@ -44,6 +61,11 @@ module MISP
44
61
  @tags = build_plural_attribute(items: attributes.dig(:Tag), klass: Tag)
45
62
  end
46
63
 
64
+ #
65
+ # Returns a hash representation of the attribute data.
66
+ #
67
+ # @return [Hash]
68
+ #
47
69
  def to_h
48
70
  {
49
71
  id: id,
@@ -66,36 +88,53 @@ module MISP
66
88
  }.compact
67
89
  end
68
90
 
91
+ #
92
+ # Get an attribute
93
+ #
94
+ # @return [MISP::Attribute]
95
+ #
69
96
  def get
70
- _get("/attributes/#{id}") { |attribute| Attribute.new symbolize_keys(attribute) }
71
- end
72
-
73
- def self.get(id)
74
- new(id: id).get
97
+ _get("/attributes/#{id}") { |attribute| Attribute.new attribute }
75
98
  end
76
99
 
100
+ #
101
+ # Delete an attribute
102
+ #
103
+ # @return [Hash]
104
+ #
77
105
  def delete
78
106
  _post("/attributes/delete/#{id}") { |json| json }
79
107
  end
80
108
 
81
- def self.delete(id)
82
- new(id: id).delete
83
- end
84
-
109
+ #
110
+ # Create an attribute
111
+ #
112
+ # @return [MISP::Attribute]
113
+ #
85
114
  def create(event_id)
86
- _post("/attributes/add/#{event_id}", wrap(to_h)) { |attribute| Attribute.new symbolize_keys(attribute) }
87
- end
88
-
89
- def self.create(event_id, **attributes)
90
- new(attributes).create(event_id)
115
+ _post("/attributes/add/#{event_id}", wrap(to_h)) { |attribute| Attribute.new attribute }
91
116
  end
92
117
 
118
+ #
119
+ # Update an attribute
120
+ #
121
+ # @param [Hash] **attrs attributes
122
+ #
123
+ # @return [MISP::Attribute]
124
+ #
93
125
  def update(**attrs)
94
126
  payload = to_h.merge(attrs)
95
127
  payload[:timestamp] = nil
96
- _post("/attributes/edit/#{id}", wrap(payload)) { |json| Attribute.new symbolize_keys(json.dig("response", "Attribute")) }
128
+ _post("/attributes/edit/#{id}", wrap(payload)) { |json| Attribute.new json.dig(:response, :Attribute) }
97
129
  end
98
130
 
131
+ #
132
+ # Search for attributes
133
+ #
134
+ # @param [Hash] **params parameters
135
+ #
136
+ # @return [Array<MISP::Attributes>]
137
+ #
99
138
  def search(**params)
100
139
  base = {
101
140
  returnFormat: "json",
@@ -104,25 +143,53 @@ module MISP
104
143
  }
105
144
 
106
145
  _post("/attributes/restSearch", base.merge(params)) do |json|
107
- attributes = json.dig("response", "Attribute") || []
108
- attributes.map { |attribute| Attribute.new symbolize_keys(attribute) }
146
+ attributes = json.dig(:response, :Attribute) || []
147
+ attributes.map { |attribute| Attribute.new attribute }
109
148
  end
110
149
  end
111
150
 
112
- def self.search(**params)
113
- new.search params
114
- end
115
-
151
+ #
152
+ # Add a tag to an attribute
153
+ #
154
+ # @param [MISP::Tag, Hash] tag
155
+ #
156
+ # @return [MISP::Tag]
157
+ #
116
158
  def add_tag(tag)
117
- tag = Tag.new(symbolize_keys(tag)) unless tag.is_a?(MISP::Tag)
159
+ tag = Tag.new(tag) unless tag.is_a?(MISP::Tag)
118
160
  payload = { uuid: uuid, tag: tag.name }
119
- _post("/tags/attachTagToObject", payload) { |json| Tag.new symbolize_keys(json) }
161
+ _post("/tags/attachTagToObject", payload) { |json| Tag.new json }
120
162
  end
121
163
 
164
+ #
165
+ # Remove a tag from an attribute
166
+ #
167
+ # @param [MISP::Tag, Hash] tag
168
+ #
169
+ # @return [Hash]
170
+ #
122
171
  def remove_tag(tag)
123
- tag = Tag.new(symbolize_keys(tag)) unless tag.is_a?(MISP::Tag)
172
+ tag = Tag.new(tag) unless tag.is_a?(MISP::Tag)
124
173
  payload = { uuid: uuid, tag: tag.name }
125
174
  _post("/tags/removeTagFromObject", payload) { |json| json }
126
175
  end
176
+
177
+ class << self
178
+ def get(id)
179
+ new(id: id).get
180
+ end
181
+
182
+ def delete(id)
183
+ new(id: id).delete
184
+ end
185
+
186
+ def create(event_id, **attributes)
187
+ new(attributes).create(event_id)
188
+ end
189
+
190
+ def search(**params)
191
+ new.search params
192
+ end
193
+ end
127
194
  end
128
195
  end
@@ -6,32 +6,59 @@ require "uri"
6
6
 
7
7
  module MISP
8
8
  class Base
9
+ private
10
+
11
+ #
12
+ # API endpoint
13
+ #
14
+ # @return [URI]
15
+ #
9
16
  def api_endpoint
10
17
  @api_endpoint ||= URI(MISP.configuration.api_endpoint)
11
18
  end
12
19
 
20
+ #
21
+ # API key
22
+ #
23
+ # @return [String]
24
+ #
13
25
  def api_key
14
26
  @api_key ||= MISP.configuration.api_key
15
27
  end
16
28
 
17
- private
18
-
29
+ #
30
+ # Build an instance of a class
31
+ #
32
+ # @param [Hash] item
33
+ # @param [Class] klass
34
+ #
35
+ # @return [Class]
36
+ #
19
37
  def build_attribute(item:, klass:)
20
38
  return nil unless item
21
39
 
22
- klass.new symbolize_keys(item)
40
+ klass.new item
23
41
  end
24
42
 
43
+ #
44
+ # Build an array of an instance of a class
45
+ #
46
+ # @param [Array<Hash>] items
47
+ # @param [Class] klass
48
+ #
49
+ # @return [Arra<Class>]
50
+ #
25
51
  def build_plural_attribute(items:, klass:)
26
52
  (items || []).map do |item|
27
- klass.new symbolize_keys(item)
53
+ klass.new item
28
54
  end
29
55
  end
30
56
 
31
- def symbolize_keys(hash)
32
- hash.map { |k, v| [k.to_sym, v] }.to_h
33
- end
34
-
57
+ #
58
+ # a name of the class
59
+ #
60
+ # @return [String]
61
+ #
35
62
  def class_name
36
63
  self.class.to_s.split("::").last.to_s
37
64
  end
@@ -39,7 +66,7 @@ module MISP
39
66
  def normalize_attributes(attributes)
40
67
  klass = class_name.to_sym
41
68
 
42
- attributes.key?(klass) ? symbolize_keys(attributes.dig(klass)) : attributes
69
+ attributes.key?(klass) ? attributes.dig(klass) : attributes
43
70
  end
44
71
 
45
72
  def wrap(params)
@@ -99,7 +126,7 @@ module MISP
99
126
  end
100
127
 
101
128
  def parse_body(body)
102
- JSON.parse body.to_s
129
+ JSON.parse body.to_s, symbolize_names: true
103
130
  rescue JSON::ParserError => _e
104
131
  body.to_s
105
132
  end
@@ -14,15 +14,15 @@ module MISP
14
14
  end
15
15
  end
16
16
 
17
- def self.configuration
18
- @configuration ||= Configuration.new
19
- end
17
+ class << self
18
+ def configuration
19
+ @configuration ||= Configuration.new
20
+ end
20
21
 
21
- def self.configuration=(config)
22
- @configuration = config
23
- end
22
+ attr_writer :configuration
24
23
 
25
- def self.configure
26
- yield configuration
24
+ def configure
25
+ yield configuration
26
+ end
27
27
  end
28
28
  end
@@ -2,33 +2,59 @@
2
2
 
3
3
  module MISP
4
4
  class Event < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_accessor :orgc_id
9
+ # @return [String]
7
10
  attr_accessor :org_id
11
+ # @return [String]
8
12
  attr_accessor :date
13
+ # @return [String]
9
14
  attr_accessor :threat_level_id
15
+ # @return [String]
10
16
  attr_accessor :info
17
+ # @return [Boolean]
11
18
  attr_accessor :published
19
+ # @return [String]
12
20
  attr_reader :uuid
21
+ # @return [String]
13
22
  attr_accessor :attribute_count
23
+ # @return [String]
14
24
  attr_accessor :analysis
25
+ # @return [String]
15
26
  attr_accessor :timestamp
27
+ # @return [String]
16
28
  attr_accessor :distribution
29
+ # @return [Boolean]
17
30
  attr_accessor :proposal_email_lock
31
+ # @return [Boolean]
18
32
  attr_accessor :locked
33
+ # @return [String]
19
34
  attr_accessor :publish_timestamp
35
+ # @return [String]
20
36
  attr_accessor :sharing_group_id
37
+ # @return [Boolean]
21
38
  attr_accessor :disable_correlation
39
+ # @return [String]
22
40
  attr_accessor :event_creator_email
23
41
 
42
+ # @return [MISP::Org, nil]
24
43
  attr_accessor :org
44
+ # @return [MISP::Orgc, nil]
25
45
  attr_accessor :orgc
26
46
 
47
+ # @return [Array<MISP::SharingGroup>]
27
48
  attr_accessor :sharing_groups
49
+ # @return [Array<MISP::Attribute>]
28
50
  attr_accessor :attributes
51
+ # @return [Array<MISP::Attribute>]
29
52
  attr_accessor :shadow_attributes
53
+ # @return [Array<MISP::Event>]
30
54
  attr_accessor :related_events
55
+ # @return [Array<<MISP::Galaxy>]
31
56
  attr_accessor :galaxies
57
+ # @return [Array<<MISP::Tag>]
32
58
  attr_accessor :tags
33
59
 
34
60
  def initialize(**attrs)
@@ -64,6 +90,11 @@ module MISP
64
90
  @tags = build_plural_attribute(items: attrs.dig(:Tag), klass: Tag)
65
91
  end
66
92
 
93
+ #
94
+ # Returns a hash representation of the attribute data.
95
+ #
96
+ # @return [Hash]
97
+ #
67
98
  def to_h
68
99
  compact(
69
100
  id: id,
@@ -95,53 +126,65 @@ module MISP
95
126
  )
96
127
  end
97
128
 
129
+ #
130
+ # Get an event
131
+ #
132
+ # @return [MISP::Event]
133
+ #
98
134
  def get(id)
99
- _get("/events/#{id}") { |event| Event.new symbolize_keys(event) }
100
- end
101
-
102
- def self.get(id)
103
- new.get id
135
+ _get("/events/#{id}") { |event| Event.new event }
104
136
  end
105
137
 
138
+ #
139
+ # Create an event
140
+ #
141
+ # @param [Hash] **attrs attributes
142
+ #
143
+ # @return [MISP::Event]
144
+ #
106
145
  def create(**attrs)
107
146
  payload = to_h.merge(attrs)
108
- _post("/events/add", wrap(payload)) { |event| Event.new symbolize_keys(event) }
109
- end
110
-
111
- def self.create(**attrs)
112
- new.create attrs
147
+ _post("/events/add", wrap(payload)) { |event| Event.new event }
113
148
  end
114
149
 
150
+ #
151
+ # Delete an event
152
+ #
153
+ # @return [Hash]
154
+ #
115
155
  def delete
116
156
  _delete("/events/#{id}") { |json| json }
117
157
  end
118
158
 
119
- def self.delete(id)
120
- new(id: id).delete
121
- end
122
-
159
+ #
160
+ # List events
161
+ #
162
+ # @return [Array<MISP::Event>]
163
+ #
123
164
  def list
124
165
  _get("/events/index") do |events|
125
166
  events.map do |event|
126
- Event.new symbolize_keys(event)
167
+ Event.new event
127
168
  end
128
169
  end
129
170
  end
130
171
 
131
- def self.list
132
- new.list
133
- end
134
-
172
+ #
173
+ # Update an event
174
+ #
175
+ # @return [MISP::Event]
176
+ #
135
177
  def update(**attrs)
136
178
  payload = to_h.merge(attrs)
137
179
  payload[:timestamp] = nil
138
- _post("/events/#{id}", wrap(payload)) { |event| Event.new symbolize_keys(event) }
139
- end
140
-
141
- def self.update(id, **attrs)
142
- new(id: id).update attrs
180
+ _post("/events/#{id}", wrap(payload)) { |event| Event.new event }
143
181
  end
144
182
 
183
+ #
184
+ # Search for events
185
+ #
186
+ # @return [Array<MISP::Event>]
187
+ #
145
188
  def search(**params)
146
189
  base = {
147
190
  returnFormat: "json",
@@ -150,27 +193,59 @@ module MISP
150
193
  }
151
194
 
152
195
  _post("/events/restSearch", base.merge(params)) do |json|
153
- events = json.dig("response") || []
154
- events.map { |event| Event.new symbolize_keys(event) }
196
+ events = json.dig(:response) || []
197
+ events.map { |event| Event.new event }
155
198
  end
156
199
  end
157
200
 
158
- def self.search(**params)
159
- new.search params
160
- end
161
-
201
+ #
202
+ # Add an attribute to an event. Requires an update or create call afterwards.
203
+ #
204
+ # @return [MISP::Event]
205
+ #
162
206
  def add_attribute(attribute)
163
- attribute = Attribute.new(symbolize_keys(attribute)) unless attribute.is_a?(Attribute)
207
+ attribute = Attribute.new(attribute) unless attribute.is_a?(Attribute)
164
208
  attributes << attribute
165
209
  self
166
210
  end
167
211
 
212
+ #
213
+ # Add a tag to an event. Requires an update or create call afterwards.
214
+ #
215
+ # @return [MISP::Event]
216
+ #
168
217
  def add_tag(tag)
169
- tag = Tag.new(symbolize_keys(tag)) unless tag.is_a?(MISP::Tag)
218
+ tag = Tag.new(tag) unless tag.is_a?(MISP::Tag)
170
219
  tags << tag
171
220
  self
172
221
  end
173
222
 
223
+ class << self
224
+ def get(id)
225
+ new.get id
226
+ end
227
+
228
+ def create(**attrs)
229
+ new.create attrs
230
+ end
231
+
232
+ def delete(id)
233
+ new(id: id).delete
234
+ end
235
+
236
+ def list
237
+ new.list
238
+ end
239
+
240
+ def update(id, **attrs)
241
+ new(id: id).update attrs
242
+ end
243
+
244
+ def search(**params)
245
+ new.search params
246
+ end
247
+ end
248
+
174
249
  private
175
250
 
176
251
  def compact(hash)
@@ -2,27 +2,49 @@
2
2
 
3
3
  module MISP
4
4
  class Feed < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :name
9
+ # @return [String]
7
10
  attr_reader :provider
11
+ # @return [String]
8
12
  attr_reader :url
13
+ # @return [String]
9
14
  attr_reader :rules
15
+ # @return [Boolean]
10
16
  attr_reader :enabled
17
+ # @return [String]
11
18
  attr_reader :distribution
19
+ # @return [String]
12
20
  attr_reader :sharing_group_id
21
+ # @return [String]
13
22
  attr_reader :tag_id
23
+ # @return [String]
14
24
  attr_reader :default
25
+ # @return [String]
15
26
  attr_reader :source_format
27
+ # @return [Boolean]
16
28
  attr_reader :fixed_event
29
+ # @return [Boolean]
17
30
  attr_reader :delta_merge
31
+ # @return [String]
18
32
  attr_reader :event_id
33
+ # @return [String]
19
34
  attr_reader :publish
35
+ # @return [String]
20
36
  attr_reader :override_ids
37
+ # @return [String]
21
38
  attr_reader :settings
39
+ # @return [String]
22
40
  attr_reader :input_source
41
+ # @return [Boolean]
23
42
  attr_reader :delete_local_file
43
+ # @return [Boolean]
24
44
  attr_reader :lookup_visible
45
+ # @return [String]
25
46
  attr_reader :headers
47
+ # @return [Boolean]
26
48
  attr_reader :caching_enabled
27
49
 
28
50
  def initialize(**attributes)
@@ -52,6 +74,11 @@ module MISP
52
74
  @caching_enabled = attributes.dig(:caching_enabled) || true
53
75
  end
54
76
 
77
+ #
78
+ # Returns a hash representation of the attribute data.
79
+ #
80
+ # @return [Hash]
81
+ #
55
82
  def to_h
56
83
  {
57
84
  id: id,
@@ -79,32 +106,51 @@ module MISP
79
106
  }.compact
80
107
  end
81
108
 
109
+ #
110
+ # List feeds
111
+ #
112
+ # @return [Array<MISP::Feed>]
113
+ #
82
114
  def list
83
115
  _get("/feeds/index") do |feeds|
84
116
  feeds.map do |feed|
85
- Feed.new symbolize_keys(feed)
117
+ Feed.new feed
86
118
  end
87
119
  end
88
120
  end
89
121
 
90
- def self.list
91
- new.list
92
- end
93
-
122
+ #
123
+ # Create a feed
124
+ #
125
+ # @return [MISP::Feed]
126
+ #
94
127
  def get
95
- _get("/feeds/view/#{id}") { |feed| Feed.new symbolize_keys(feed) }
96
- end
97
-
98
- def self.get(id)
99
- new(id: id).get
128
+ _get("/feeds/view/#{id}") { |feed| Feed.new feed }
100
129
  end
101
130
 
131
+ #
132
+ # Create a feed
133
+ #
134
+ # @param [Hash] **attributes attributes
135
+ #
136
+ # @return [MIPS::Feed]
137
+ #
102
138
  def create(**attributes)
103
- _post("/feeds/add", wrap(attributes)) { |feed| Feed.new symbolize_keys(feed) }
139
+ _post("/feeds/add", wrap(attributes)) { |feed| Feed.new feed }
104
140
  end
105
141
 
106
- def self.create(attributes)
107
- new.create attributes
142
+ class << self
143
+ def list
144
+ new.list
145
+ end
146
+
147
+ def get(id)
148
+ new(id: id).get
149
+ end
150
+
151
+ def create(**attributes)
152
+ new.create attributes
153
+ end
108
154
  end
109
155
  end
110
156
  end
@@ -2,13 +2,20 @@
2
2
 
3
3
  module MISP
4
4
  class Galaxy < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :uuid
9
+ # @return [String]
7
10
  attr_reader :name
11
+ # @return [String]
8
12
  attr_reader :type
13
+ # @return [String]
9
14
  attr_reader :description
15
+ # @return [String]
10
16
  attr_reader :version
11
17
 
18
+ # @return [Array<MISP::GalaxyCluster>]
12
19
  attr_reader :galaxy_clusters
13
20
 
14
21
  def initialize(**attributes)
@@ -24,6 +31,11 @@ module MISP
24
31
  @galaxy_clusters = build_plural_attribute(items: attributes.dig(:GalaxyCluster), klass: GalaxyCluster)
25
32
  end
26
33
 
34
+ #
35
+ # Returns a hash representation of the attribute data.
36
+ #
37
+ # @return [Hash]
38
+ #
27
39
  def to_h
28
40
  {
29
41
  id: id,
@@ -36,24 +48,36 @@ module MISP
36
48
  }.compact
37
49
  end
38
50
 
51
+ #
52
+ # List galaxies
53
+ #
54
+ # @return [Array<Galaxy>]
55
+ #
39
56
  def list
40
57
  _get("/galaxies/") do |galaxies|
41
58
  galaxies.map do |galaxy|
42
- Galaxy.new symbolize_keys(galaxy)
59
+ Galaxy.new galaxy
43
60
  end
44
61
  end
45
62
  end
46
63
 
47
- def self.list
48
- new.list
49
- end
50
-
64
+ #
65
+ # Get a galaxy
66
+ #
67
+ # @return [MISP::Galaxy]
68
+ #
51
69
  def get
52
- _get("/galaxies/view/#{id}") { |galaxy| Galaxy.new symbolize_keys(galaxy) }
70
+ _get("/galaxies/view/#{id}") { |galaxy| Galaxy.new galaxy }
53
71
  end
54
72
 
55
- def self.get(id)
56
- new(id: id).get
73
+ class << self
74
+ def list
75
+ new.list
76
+ end
77
+
78
+ def get(id)
79
+ new(id: id).get
80
+ end
57
81
  end
58
82
  end
59
83
  end
@@ -2,16 +2,27 @@
2
2
 
3
3
  module MISP
4
4
  class GalaxyCluster < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :uuid
9
+ # @return [String]
7
10
  attr_reader :type
11
+ # @return [String]
8
12
  attr_reader :value
13
+ # @return [String]
9
14
  attr_reader :tag_name
15
+ # @return [String]
10
16
  attr_reader :description
17
+ # @return [String]
11
18
  attr_reader :galaxy_id
19
+ # @return [String]
12
20
  attr_reader :source
21
+ # @return [Array<String>]
13
22
  attr_reader :authors
23
+ # @return [String]
14
24
  attr_reader :tag_id
25
+ # @return [Hash]
15
26
  attr_reader :meta
16
27
 
17
28
  def initialize(**attributes)
@@ -30,6 +41,11 @@ module MISP
30
41
  @meta = attributes.dig(:meta)
31
42
  end
32
43
 
44
+ #
45
+ # Returns a hash representation of the attribute data.
46
+ #
47
+ # @return [Hash]
48
+ #
33
49
  def to_h
34
50
  {
35
51
  id: id,
@@ -2,8 +2,11 @@
2
2
 
3
3
  module MISP
4
4
  class Org < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :name
9
+ # @return [String]
7
10
  attr_reader :uuid
8
11
 
9
12
  def initialize(**attributes)
@@ -14,6 +17,11 @@ module MISP
14
17
  @uuid = attributes.dig(:uuid)
15
18
  end
16
19
 
20
+ #
21
+ # Returns a hash representation of the attribute data.
22
+ #
23
+ # @return [Hash]
24
+ #
17
25
  def to_h
18
26
  {
19
27
  id: id,
@@ -2,8 +2,11 @@
2
2
 
3
3
  module MISP
4
4
  class Orgc < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :name
9
+ # @return [String]
7
10
  attr_reader :uuid
8
11
 
9
12
  def initialize(**attributes)
@@ -14,6 +17,11 @@ module MISP
14
17
  @uuid = attributes.dig(:uuid)
15
18
  end
16
19
 
20
+ #
21
+ # Returns a hash representation of the attribute data.
22
+ #
23
+ # @return [Hash]
24
+ #
17
25
  def to_h
18
26
  {
19
27
  id: id,
@@ -2,8 +2,11 @@
2
2
 
3
3
  module MISP
4
4
  class Server < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :url
9
+ # @return [String]
7
10
  attr_reader :name
8
11
 
9
12
  def initialize(**attributes)
@@ -14,6 +17,11 @@ module MISP
14
17
  @name = attributes.dig(:name)
15
18
  end
16
19
 
20
+ #
21
+ # Returns a hash representation of the attribute data.
22
+ #
23
+ # @return [Hash]
24
+ #
17
25
  def to_h
18
26
  {
19
27
  id: id,
@@ -22,16 +30,23 @@ module MISP
22
30
  }.compact
23
31
  end
24
32
 
33
+ #
34
+ # List servers
35
+ #
36
+ # @return [Array<MISP::Server>]
37
+ #
25
38
  def list
26
39
  _get("/servers/") do |servers|
27
40
  servers.map do |server|
28
- Server.new symbolize_keys(server)
41
+ Server.new server
29
42
  end
30
43
  end
31
44
  end
32
45
 
33
- def self.list
34
- new.list
46
+ class << self
47
+ def list
48
+ new.list
49
+ end
35
50
  end
36
51
  end
37
52
  end
@@ -1,21 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MISP
4
- class SharingGroup < Server
4
+ class SharingGroup < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :name
9
+ # @return [String]
7
10
  attr_reader :releasability
11
+ # @return [String]
8
12
  attr_reader :description
13
+ # @return [String]
9
14
  attr_reader :uuid
15
+ # @return [String]
10
16
  attr_reader :organisation_uuid
17
+ # @return [String]
11
18
  attr_reader :org_id
19
+ # @return [String]
12
20
  attr_reader :sync_user_id
21
+ # @return [Boolean]
13
22
  attr_reader :active
23
+ # @return [String]
14
24
  attr_reader :created
25
+ # @return [String]
15
26
  attr_reader :modified
27
+ # @return [Boolean]
16
28
  attr_reader :local
29
+ # @return [Boolean]
17
30
  attr_reader :roaming
18
31
 
32
+ # @return [MISP::Org, nil]
33
+ attr_reader :organization
34
+
35
+ # @return [Array<MISP::SharingGroupOrg>]
36
+ attr_reader :sharing_group_orgs
37
+ # @return [Array<MISP::SharingGroupServer>]
38
+ attr_reader :sharing_group_servers
39
+
19
40
  def initialize(**attributes)
20
41
  attributes = normalize_attributes(attributes)
21
42
 
@@ -33,12 +54,17 @@ module MISP
33
54
  @local = attributes.dig(:local)
34
55
  @roaming = attributes.dig(:roaming)
35
56
 
36
- @_organisation = attributes.dig(:Organisation)
57
+ @organisation = build_attribute(item: attributes.dig(:Organization), klass: Org)
37
58
 
38
59
  @sharing_group_orgs = build_plural_attribute(items: attributes.dig(:SharingGroupOrg), klass: SharingGroupOrg)
39
60
  @sharing_group_servers = build_plural_attribute(items: attributes.dig(:SharingGroupServer), klass: SharingGroupServer)
40
61
  end
41
62
 
63
+ #
64
+ # Returns a hash representation of the attribute data.
65
+ #
66
+ # @return [Hash]
67
+ #
42
68
  def to_h
43
69
  {
44
70
  id: id,
@@ -60,25 +86,39 @@ module MISP
60
86
  }.compact
61
87
  end
62
88
 
89
+ #
90
+ # List sharing groups
91
+ #
92
+ # @return [Array<MISP::SharingGroup>]
93
+ #
63
94
  def list
64
95
  _get("/sharing_groups/") do |res|
65
- sharing_groups = res.dig("response") || []
96
+ sharing_groups = res.dig(:response) || []
66
97
  sharing_groups.map do |sharing_group|
67
- SharingGroup.new symbolize_keys(sharing_group)
98
+ SharingGroup.new sharing_group
68
99
  end
69
100
  end
70
101
  end
71
102
 
72
- def self.list
73
- new.list
74
- end
75
-
103
+ #
104
+ # Create a sharing group
105
+ #
106
+ # @param [Hash] **attributes attributes
107
+ #
108
+ # @return [MISP::SharingGroup]
109
+ #
76
110
  def create(**attributes)
77
- _post("/sharing_groups/add", wrap(attributes)) { |sharing_group| SharingGroup.new symbolize_keys(sharing_group) }
111
+ _post("/sharing_groups/add", wrap(attributes)) { |sharing_group| SharingGroup.new sharing_group }
78
112
  end
79
113
 
80
- def self.create(attributes)
81
- new.create attributes
114
+ class << self
115
+ def list
116
+ new.list
117
+ end
118
+
119
+ def create(**attributes)
120
+ new.create attributes
121
+ end
82
122
  end
83
123
  end
84
124
  end
@@ -1,12 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MISP
4
- class SharingGroupOrg < Server
4
+ class SharingGroupOrg < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :sharing_group_id
9
+ # @return [String]
7
10
  attr_reader :org_id
11
+ # @return [String]
8
12
  attr_reader :extend
9
13
 
14
+ # @return [MISP::Organization, nil]
10
15
  attr_reader :organization
11
16
 
12
17
  def initialize(**attributes)
@@ -20,6 +25,11 @@ module MISP
20
25
  @organization = build_attribute(item: attributes.dig(:Organization), klass: Org)
21
26
  end
22
27
 
28
+ #
29
+ # Returns a hash representation of the attribute data.
30
+ #
31
+ # @return [Hash]
32
+ #
23
33
  def to_h
24
34
  {
25
35
  erver: erver,
@@ -1,12 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MISP
4
- class SharingGroupServer < Server
4
+ class SharingGroupServer < Base
5
+ # @return [String]
5
6
  attr_reader :id
7
+ # @return [String]
6
8
  attr_reader :sharing_group_id
9
+ # @return [String]
7
10
  attr_reader :server_id
11
+ # @return [Boolean]
8
12
  attr_reader :all_orgs
9
13
 
14
+ # @return [Array<MISP::Server>]
10
15
  attr_reader :servers
11
16
 
12
17
  def initialize(**attributes)
@@ -20,6 +25,11 @@ module MISP
20
25
  @servers = build_plural_attribute(items: attributes.dig(:Server), klass: Server)
21
26
  end
22
27
 
28
+ #
29
+ # Returns a hash representation of the attribute data.
30
+ #
31
+ # @return [Hash]
32
+ #
23
33
  def to_h
24
34
  {
25
35
  id: id,
@@ -2,10 +2,15 @@
2
2
 
3
3
  module MISP
4
4
  class Tag < Base
5
+ # @return [String]
5
6
  attr_accessor :id
7
+ # @return [String]
6
8
  attr_accessor :name
9
+ # @return [String]
7
10
  attr_accessor :colour
11
+ # @return [Boolean]
8
12
  attr_accessor :exportable
13
+ # @return [Boolean]
9
14
  attr_accessor :hide_tag
10
15
 
11
16
  def initialize(**attributes)
@@ -18,6 +23,11 @@ module MISP
18
23
  @hide_tag = attributes.dig(:hide_tag)
19
24
  end
20
25
 
26
+ #
27
+ # Returns a hash representation of the attribute data.
28
+ #
29
+ # @return [Hash]
30
+ #
21
31
  def to_h
22
32
  {
23
33
  id: id,
@@ -28,42 +38,75 @@ module MISP
28
38
  }.compact
29
39
  end
30
40
 
31
- def get(id)
32
- _get("/tags/view/#{id}") { |json| Tag.new symbolize_keys(json) }
41
+ #
42
+ # Get a tag
43
+ #
44
+ # @return [MISP::Tag]
45
+ #
46
+ def get
47
+ _get("/tags/view/#{id}") { |json| Tag.new json }
33
48
  end
34
49
 
35
- def self.get(id)
36
- new.get id
37
- end
38
-
39
- def create(attributes)
40
- _post("/tags/add", wrap(attributes)) { |json| Tag.new symbolize_keys(json) }
41
- end
42
-
43
- def self.create(attributes)
44
- new.create attributes
50
+ #
51
+ # Create a tag
52
+ #
53
+ # @param [Hash] **attributes attributes
54
+ #
55
+ # @return [MISP::Tag]
56
+ #
57
+ def create(**attributes)
58
+ _post("/tags/add", wrap(attributes)) { |json| Tag.new json }
45
59
  end
46
60
 
61
+ #
62
+ # Delete a tag
63
+ #
64
+ # @return [Hash]
65
+ #
47
66
  def delete
48
67
  _post("/tags/delete/#{id}") { |json| json }
49
68
  end
50
69
 
51
- def self.delete(id)
52
- Tag.new(id: id).delete
53
- end
54
-
70
+ #
71
+ # Update a tag
72
+ #
73
+ # @param [Hash] **attributes attributes
74
+ #
75
+ # @return [MISP::Tag]
76
+ #
55
77
  def update(**attributes)
56
78
  payload = to_h.merge(attributes)
57
- _post("/tags/edit/#{id}", wrap(payload)) { |json| Tag.new symbolize_keys(json) }
58
- end
59
-
60
- def self.update(id, **attributes)
61
- Tag.new(id: id).update attributes
79
+ _post("/tags/edit/#{id}", wrap(payload)) { |json| Tag.new json }
62
80
  end
63
81
 
82
+ #
83
+ # Search for tags
84
+ #
85
+ # @param [Hash] **params parameters
86
+ #
87
+ # @return [MISP::Tag]
88
+ #
64
89
  def search(**params)
65
90
  _post("/tags/search", params) do |tags|
66
- tags.map { |tag| Tag.new symbolize_keys(tag) }
91
+ tags.map { |tag| Tag.new tag }
92
+ end
93
+ end
94
+
95
+ class << self
96
+ def get(id)
97
+ new(id: id).get
98
+ end
99
+
100
+ def create(**attributes)
101
+ new.create attributes
102
+ end
103
+
104
+ def delete(id)
105
+ Tag.new(id: id).delete
106
+ end
107
+
108
+ def update(id, **attributes)
109
+ Tag.new(id: id).update attributes
67
110
  end
68
111
  end
69
112
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MISP
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
@@ -26,8 +26,8 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_development_dependency "bundler", "~> 2.0"
28
28
  spec.add_development_dependency "coveralls", "~> 0.8"
29
- spec.add_development_dependency "rake", "~> 12.3"
29
+ spec.add_development_dependency "rake", "~> 13.0"
30
30
  spec.add_development_dependency "rspec", "~> 3.8"
31
31
  spec.add_development_dependency "vcr", "~> 5.0"
32
- spec.add_development_dependency "webmock", "~> 3.6"
32
+ spec.add_development_dependency "webmock", "~> 3.7"
33
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: misp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manabu Niseki
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-22 00:00:00.000000000 Z
11
+ date: 2019-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '12.3'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '12.3'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '3.6'
89
+ version: '3.7'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '3.6'
96
+ version: '3.7'
97
97
  description: A dead simple MISP API wrapper for Ruby
98
98
  email:
99
99
  - manabu.niseki@gmail.com