# frozen_string_literal: true module MISP class Event < Base # @return [String] attr_reader :id # @return [String] attr_accessor :orgc_id # @return [String] attr_accessor :org_id # @return [String] attr_accessor :date # @return [String] attr_accessor :threat_level_id # @return [String] attr_accessor :info # @return [Boolean] attr_accessor :published # @return [String] attr_reader :uuid # @return [String] attr_accessor :attribute_count # @return [String] attr_accessor :analysis # @return [String] attr_accessor :timestamp # @return [String] attr_accessor :distribution # @return [Boolean] attr_accessor :proposal_email_lock # @return [Boolean] attr_accessor :locked # @return [String] attr_accessor :publish_timestamp # @return [String] attr_accessor :sharing_group_id # @return [Boolean] attr_accessor :disable_correlation # @return [String] attr_accessor :event_creator_email # @return [MISP::Org, nil] attr_accessor :org # @return [MISP::Orgc, nil] attr_accessor :orgc # @return [Array] attr_accessor :sharing_groups # @return [Array] attr_accessor :attributes # @return [Array] attr_accessor :shadow_attributes # @return [Array] attr_accessor :related_events # @return [Array<] attr_accessor :galaxies # @return [Array<] attr_accessor :tags def initialize(**attrs) attrs = normalize_attributes(**attrs) @id = attrs[:id] @orgc_id = attrs[:orgc_id] @org_id = attrs[:org_id] @date = attrs[:date] @threat_level_id = attrs[:threat_level_id] @info = attrs[:info] @published = attrs[:published] || false @uuid = attrs[:uuid] @attribute_count = attrs[:attribute_count] @analysis = attrs[:analysis] @timestamp = attrs[:timestamp] @distribution = attrs[:distribution] @proposal_email_lock = attrs[:proposal_email_lock] @locked = attrs[:locked] || false @publish_timestamp = attrs[:publish_timestamp] @sharing_group_id = attrs[:sharing_group_id] @disable_correlation = attrs[:disable_correlation] @event_creator_email = attrs[:event_creator_email] @org = build_attribute(item: attrs[:Org], klass: Org) @orgc = build_attribute(item: attrs[:Orgc], klass: Orgc) @sharing_groups = build_plural_attribute(items: attrs[:SharingGroup], klass: SharingGroup) @attributes = build_plural_attribute(items: attrs[:Attribute], klass: Attribute) @shadow_attributes = build_plural_attribute(items: attrs[:ShadowAttribute], klass: Attribute ) @related_events = build_plural_attribute(items: attrs[:RelatedEvent], klass: Attribute) @galaxies = build_plural_attribute(items: attrs[:Galaxy], klass: Galaxy) @tags = build_plural_attribute(items: attrs[:Tag], klass: Tag) end # # Returns a hash representation of the attribute data. # # @return [Hash] # def to_h compact( id: id, orgc_id: orgc_id, org_id: org_id, date: date, threat_level_id: threat_level_id, info: info, published: published, uuid: uuid, attribute_count: attribute_count, analysis: analysis, timestamp: timestamp, distribution: distribution, proposal_email_lock: proposal_email_lock, locked: locked, publish_timestamp: publish_timestamp, sharing_group_id: sharing_group_id, disable_correlation: disable_correlation, event_creator_email: event_creator_email, Org: org.to_h, Orgc: orgc.to_h, SharingGroup: sharing_groups.map(&:to_h), Attribute: attributes.map(&:to_h), ShadowAttribute: shadow_attributes.map(&:to_h), RelatedEvent: related_events.map(&:to_h), Galaxy: galaxies.map(&:to_h), Tag: tags.map(&:to_h) ) end # # Get an event # # @return [MISP::Event] # def get(id) _get("/events/#{id}") { |event| Event.new(**event) } end # # Create an event # # @param [Hash] **attrs attributes # # @return [MISP::Event] # def create(**attrs) payload = to_h.merge(attrs) _post("/events/add", wrap(payload)) { |event| Event.new(**event) } end # # Delete an event # # @return [Hash] # def delete _delete("/events/#{id}") { |json| json } end # # List events # # @return [Array] # def list _get("/events/index") do |events| events.map do |event| Event.new(**event) end end end # # Update an event # # @return [MISP::Event] # def update(**attrs) payload = to_h.merge(**attrs) payload[:timestamp] = nil _post("/events/#{id}", wrap(payload)) { |event| Event.new(**event) } end # # Search for events # # @return [Array] # def search(**params) base = { returnFormat: "json", limit: "100", page: "0" } _post("/events/restSearch", base.merge(params)) do |json| events = json[:response] || [] events.map { |event| Event.new(**event) } end end # # Add an attribute to an event. Requires an update or create call afterwards. # # @return [MISP::Event] # def add_attribute(attribute) attribute = Attribute.new(**attribute) unless attribute.is_a?(Attribute) attributes << attribute self end # # Add a tag to an event. Requires an update or create call afterwards. # # @return [MISP::Event] # def add_tag(tag) tag = Tag.new(**tag) unless tag.is_a?(MISP::Tag) tags << tag self end class << self def get(id) new.get id end def create(**attrs) new.create(**attrs) end def delete(id) new(id: id).delete end def list new.list end def update(id, **attrs) new(id: id).update(**attrs) end def search(**params) new.search(**params) end end private def compact(hash) hash.compact.reject { |_k, v| (v.is_a?(Hash) || v.is_a?(Array)) && v.empty? } end end end