summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/agents/events_controller.rb8
-rw-r--r--app/controllers/agents/files_controller.rb28
-rw-r--r--app/controllers/agents_controller.rb60
-rw-r--r--app/controllers/api/agents/events_controller.rb22
-rw-r--r--app/controllers/api/agents/files_controller.rb20
-rw-r--r--app/controllers/api/agents_controller.rb11
-rw-r--r--app/controllers/api/api_controller.rb10
-rw-r--r--app/controllers/application_controller.rb9
-rw-r--r--app/controllers/dispositions_controller.rb55
-rw-r--r--app/models/agent.rb2
-rw-r--r--app/models/event.rb2
-rw-r--r--app/models/event_message.rb25
-rw-r--r--app/models/poke_message.rb23
-rw-r--r--app/models/scanned.rb2
-rw-r--r--app/services/publisher.rb4
-rw-r--r--app/views/agents/index.html.erb7
-rw-r--r--app/views/api/agents/create.json.jbuilder (renamed from app/views/agents/show.json.jbuilder)0
-rw-r--r--app/views/api/agents/files/index.json.jbuilder (renamed from app/views/agents/files/index.json.jbuilder)0
-rw-r--r--app/views/api/agents/files/show.json.jbuilder (renamed from app/views/agents/files/show.json.jbuilder)0
-rw-r--r--app/views/api/agents/index.json.jbuilder (renamed from app/views/agents/index.json.jbuilder)0
-rw-r--r--app/views/dispositions/index.json.jbuilder4
-rw-r--r--app/views/dispositions/show.json.jbuilder1
-rw-r--r--app/workers/event_intake.rb15
23 files changed, 179 insertions, 129 deletions
diff --git a/app/controllers/agents/events_controller.rb b/app/controllers/agents/events_controller.rb
index 6827938..f695feb 100644
--- a/app/controllers/agents/events_controller.rb
+++ b/app/controllers/agents/events_controller.rb
@@ -11,9 +11,11 @@ module Agents
end
def create
- message = event_params.merge({agent_id: @agent.id})
- routing_key = "events.#{event_params[:type]}.#{@agent.id}"
- Publisher.publish(routing_key, message)
+ publish(EventMessage.new(
+ agent_id: @agent.id,
+ event_type: event_params[:type],
+ data: event_params[:data]
+ ))
redirect_to agent_events_url, notice: 'Event was successfully created.'
end
diff --git a/app/controllers/agents/files_controller.rb b/app/controllers/agents/files_controller.rb
deleted file mode 100644
index 0f493fb..0000000
--- a/app/controllers/agents/files_controller.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Agents
- class FilesController < ApplicationController
- before_action :load_agent
- before_action do
- request.format = :json
- end
-
- def index
- end
-
- def show
- @fingerprint = params[:id]
- @file = Disposition.find_by(fingerprint: params[:id])
- message = {
- agent_id: params[:id],
- type: :lookup,
- data: params[:data]
- }
- Publisher.publish("events.scanned.#{@agent.id}", message)
- end
-
- private
-
- def load_agent
- @agent = Agent.find(params[:agent_id])
- end
- end
-end
diff --git a/app/controllers/agents_controller.rb b/app/controllers/agents_controller.rb
index a76a7ae..dc2717a 100644
--- a/app/controllers/agents_controller.rb
+++ b/app/controllers/agents_controller.rb
@@ -1,74 +1,48 @@
class AgentsController < ApplicationController
- before_action :set_agent, only: [:show, :edit, :update, :destroy]
-
- # GET /agents
- # GET /agents.json
def index
- @agents = Agent.all
+ @agents = Agent.all.order(created_at: :desc)
end
- # GET /agents/1
- # GET /agents/1.json
def show
+ @agent = Agent.find(params[:id])
end
- # GET /agents/new
def new
@agent = Agent.new
end
- # GET /agents/1/edit
def edit
+ @agent = Agent.find(params[:id])
end
- # POST /agents
- # POST /agents.json
def create
@agent = Agent.new(agent_params)
- respond_to do |format|
- if @agent.save
- format.html { redirect_to @agent, notice: 'Agent was successfully created.' }
- format.json { render :show, status: :created, location: @agent }
- else
- format.html { render :new }
- format.json { render json: @agent.errors, status: :unprocessable_entity }
- end
+ if @agent.save
+ redirect_to @agent, notice: 'Agent was successfully created.'
+ else
+ render :new
end
end
- # PATCH/PUT /agents/1
- # PATCH/PUT /agents/1.json
def update
- respond_to do |format|
- if @agent.update(agent_params)
- format.html { redirect_to @agent, notice: 'Agent was successfully updated.' }
- format.json { render :show, status: :ok, location: @agent }
- else
- format.html { render :edit }
- format.json { render json: @agent.errors, status: :unprocessable_entity }
- end
+ @agent = Agent.find(params[:id])
+ if @agent.update(agent_params)
+ redirect_to @agent, notice: 'Agent was successfully updated.'
+ else
+ render :edit
end
end
- # DELETE /agents/1
- # DELETE /agents/1.json
def destroy
+ @agent = Agent.find(params[:id])
@agent.destroy
- respond_to do |format|
- format.html { redirect_to agents_url, notice: 'Agent was successfully destroyed.' }
- format.json { head :no_content }
- end
+ redirect_to agents_url, notice: 'Agent was successfully destroyed.'
end
private
- # Use callbacks to share common setup or constraints between actions.
- def set_agent
- @agent = Agent.find(params[:id])
- end
- # Never trust parameters from the scary internet, only allow the white list through.
- def agent_params
- params.require(:agent).permit(:hostname)
- end
+ def agent_params
+ params.require(:agent).permit(:hostname)
+ end
end
diff --git a/app/controllers/api/agents/events_controller.rb b/app/controllers/api/agents/events_controller.rb
new file mode 100644
index 0000000..56b566f
--- /dev/null
+++ b/app/controllers/api/agents/events_controller.rb
@@ -0,0 +1,22 @@
+module Api
+ module Agents
+ class EventsController < ApiController
+ def create
+ @agent = Agent.find(params[:agent_id])
+ publish(EventMessage.new(
+ agent_id: @agent.id,
+ event_type: event_params[:type],
+ data: event_params[:data]
+ ))
+
+ render nothing: true
+ end
+
+ private
+
+ def event_params
+ params[:event]
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/agents/files_controller.rb b/app/controllers/api/agents/files_controller.rb
new file mode 100644
index 0000000..c13eac9
--- /dev/null
+++ b/app/controllers/api/agents/files_controller.rb
@@ -0,0 +1,20 @@
+module Api
+ module Agents
+ class FilesController < ApiController
+ before_action do
+ request.format = :json
+ end
+
+ def show
+ @agent = Agent.find(params[:agent_id])
+ @fingerprint = params[:id]
+ @file = Disposition.find_by(fingerprint: params[:id])
+ publish(EventMessage.new(
+ agent_id: @agent.id,
+ event_type: :scanned,
+ data: params[:data]
+ ))
+ end
+ end
+ end
+end
diff --git a/app/controllers/api/agents_controller.rb b/app/controllers/api/agents_controller.rb
new file mode 100644
index 0000000..a7307f0
--- /dev/null
+++ b/app/controllers/api/agents_controller.rb
@@ -0,0 +1,11 @@
+module Api
+ class AgentsController < ApiController
+ def create
+ @agent = Agent.create!(agent_params)
+ end
+
+ def agent_params
+ params.require(:agent).permit(:hostname)
+ end
+ end
+end
diff --git a/app/controllers/api/api_controller.rb b/app/controllers/api/api_controller.rb
new file mode 100644
index 0000000..6954700
--- /dev/null
+++ b/app/controllers/api/api_controller.rb
@@ -0,0 +1,10 @@
+module Api
+ class ApiController < ActionController::Base
+ protect_from_forgery with: :null_session
+ protected
+
+ def publish(message)
+ Publisher.publish(message)
+ end
+ end
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 38aeade..63e2ed4 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,10 +1,15 @@
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
- #protect_from_forgery with: :exception
- protect_from_forgery with: :null_session
+ protect_from_forgery with: :exception
before_action :authorize!
+ protected
+
+ def publish(message)
+ Publisher.publish(message)
+ end
+
private
def authorize!
diff --git a/app/controllers/dispositions_controller.rb b/app/controllers/dispositions_controller.rb
index 116b7bb..dc3112a 100644
--- a/app/controllers/dispositions_controller.rb
+++ b/app/controllers/dispositions_controller.rb
@@ -1,68 +1,51 @@
class DispositionsController < ApplicationController
before_action :set_disposition, only: [:show, :edit, :update, :destroy]
- # GET /dispositions
- # GET /dispositions.json
def index
- @dispositions = Disposition.all
+ @dispositions = Disposition.all.order(:fingerprint)
end
- # GET /dispositions/1
- # GET /dispositions/1.json
def show
end
- # GET /dispositions/new
def new
@disposition = Disposition.new
@states = Disposition.states
end
- # GET /dispositions/1/edit
def edit
@states = Disposition.states
end
- # POST /dispositions
- # POST /dispositions.json
def create
- fingerprint = disposition_params[:fingerprint]
- Publisher.publish("commands.poke.#{fingerprint}", disposition_params)
+ publish(PokeMessage.new(
+ fingerprint: disposition_params[:fingerprint],
+ state: disposition_params[:state],
+ ))
- respond_to do |format|
- format.html { redirect_to dispositions_path, notice: 'Disposition was successfully created.' }
- format.json { head :no_content }
- end
+ redirect_to dispositions_path, notice: 'Disposition was successfully created.'
end
- # PATCH/PUT /dispositions/1
- # PATCH/PUT /dispositions/1.json
def update
- Publisher.publish("poke", disposition_params)
- respond_to do |format|
- format.html { redirect_to dispositions_path, notice: 'Disposition was successfully updated.' }
- format.json { head :no_content }
- end
+ publish(PokeMessage.new(
+ fingerprint: disposition_params[:fingerprint],
+ state: disposition_params[:state],
+ ))
+ redirect_to dispositions_path, notice: 'Disposition was successfully updated.'
end
- # DELETE /dispositions/1
- # DELETE /dispositions/1.json
def destroy
@disposition.destroy
- respond_to do |format|
- format.html { redirect_to dispositions_url, notice: 'Disposition was successfully destroyed.' }
- format.json { head :no_content }
- end
+ redirect_to dispositions_url, notice: 'Disposition was successfully destroyed.'
end
private
- # Use callbacks to share common setup or constraints between actions.
- def set_disposition
- @disposition = Disposition.find_by(fingerprint: params[:id])
- end
- # Never trust parameters from the scary internet, only allow the white list through.
- def disposition_params
- params.require(:disposition).permit(:fingerprint, :state)
- end
+ def set_disposition
+ @disposition = Disposition.find_by(fingerprint: params[:id])
+ end
+
+ def disposition_params
+ params.require(:disposition).permit(:fingerprint, :state)
+ end
end
diff --git a/app/models/agent.rb b/app/models/agent.rb
index e5832da..d33a970 100644
--- a/app/models/agent.rb
+++ b/app/models/agent.rb
@@ -1,3 +1,3 @@
class Agent < ActiveRecord::Base
- has_many :events
+ has_many :events, dependent: :destroy
end
diff --git a/app/models/event.rb b/app/models/event.rb
index 8124b3f..0377c25 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -1,4 +1,4 @@
class Event < ActiveRecord::Base
belongs_to :agent
- has_secure_password
+ validates_presence_of :agent
end
diff --git a/app/models/event_message.rb b/app/models/event_message.rb
new file mode 100644
index 0000000..75bd9ac
--- /dev/null
+++ b/app/models/event_message.rb
@@ -0,0 +1,25 @@
+class EventMessage
+ attr_reader :agent_id, :event_type, :data
+
+ def initialize(agent_id:, event_type:, data: {})
+ @agent_id = agent_id
+ @event_type = event_type
+ @data = data
+ end
+
+ def routing_key
+ "events.#{event_type}.#{agent_id}"
+ end
+
+ def to_hash
+ {
+ agent_id: agent_id,
+ type: event_type,
+ data: data
+ }
+ end
+
+ def to_json
+ to_hash.to_json
+ end
+end
diff --git a/app/models/poke_message.rb b/app/models/poke_message.rb
new file mode 100644
index 0000000..b134ba9
--- /dev/null
+++ b/app/models/poke_message.rb
@@ -0,0 +1,23 @@
+class PokeMessage
+ attr_reader :fingerprint, :state
+
+ def initialize(fingerprint:, state: )
+ @fingerprint = fingerprint
+ @state = state
+ end
+
+ def routing_key
+ "commands.poke.#{fingerprint}"
+ end
+
+ def to_hash
+ {
+ fingerprint: fingerprint,
+ state: state
+ }
+ end
+
+ def to_json
+ to_hash.to_json
+ end
+end
diff --git a/app/models/scanned.rb b/app/models/scanned.rb
new file mode 100644
index 0000000..cfe1b87
--- /dev/null
+++ b/app/models/scanned.rb
@@ -0,0 +1,2 @@
+class Scanned < Event
+end
diff --git a/app/services/publisher.rb b/app/services/publisher.rb
index 704f1e3..1c384dd 100644
--- a/app/services/publisher.rb
+++ b/app/services/publisher.rb
@@ -1,7 +1,7 @@
class Publisher
- def self.publish(routing_key, message = {})
+ def self.publish(message)
exchange = channel.topic("malwer")
- exchange.publish(message.to_json, routing_key: routing_key)
+ exchange.publish(message.to_json, routing_key: message.routing_key)
end
def self.channel
diff --git a/app/views/agents/index.html.erb b/app/views/agents/index.html.erb
index 3a6b738..75adfdb 100644
--- a/app/views/agents/index.html.erb
+++ b/app/views/agents/index.html.erb
@@ -9,15 +9,16 @@
<thead>
<tr>
<th>Hostname</th>
- <th colspan="4"></th>
+ <th>Created At</th>
+ <th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @agents.each do |agent| %>
<tr>
- <td><%= agent.hostname %></td>
+ <td><%= link_to agent.hostname, agent_path(agent) %></td>
+ <td><%= agent.created_at %></td>
<td><%= link_to 'Events', agent_events_path(agent) %></td>
- <td><%= link_to 'Show', agent %></td>
<td><%= link_to 'Edit', edit_agent_path(agent) %></td>
<td><%= link_to 'Destroy', agent, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
diff --git a/app/views/agents/show.json.jbuilder b/app/views/api/agents/create.json.jbuilder
index f156cb0..f156cb0 100644
--- a/app/views/agents/show.json.jbuilder
+++ b/app/views/api/agents/create.json.jbuilder
diff --git a/app/views/agents/files/index.json.jbuilder b/app/views/api/agents/files/index.json.jbuilder
index 6551a44..6551a44 100644
--- a/app/views/agents/files/index.json.jbuilder
+++ b/app/views/api/agents/files/index.json.jbuilder
diff --git a/app/views/agents/files/show.json.jbuilder b/app/views/api/agents/files/show.json.jbuilder
index 8c6f501..8c6f501 100644
--- a/app/views/agents/files/show.json.jbuilder
+++ b/app/views/api/agents/files/show.json.jbuilder
diff --git a/app/views/agents/index.json.jbuilder b/app/views/api/agents/index.json.jbuilder
index 65f6f60..65f6f60 100644
--- a/app/views/agents/index.json.jbuilder
+++ b/app/views/api/agents/index.json.jbuilder
diff --git a/app/views/dispositions/index.json.jbuilder b/app/views/dispositions/index.json.jbuilder
deleted file mode 100644
index d4350e1..0000000
--- a/app/views/dispositions/index.json.jbuilder
+++ /dev/null
@@ -1,4 +0,0 @@
-json.array!(@dispositions) do |disposition|
- json.extract! disposition, :fingerprint, :state
- json.url disposition_url(disposition, format: :json)
-end
diff --git a/app/views/dispositions/show.json.jbuilder b/app/views/dispositions/show.json.jbuilder
deleted file mode 100644
index 7046781..0000000
--- a/app/views/dispositions/show.json.jbuilder
+++ /dev/null
@@ -1 +0,0 @@
-json.extract! @disposition, :fingerprint, :state
diff --git a/app/workers/event_intake.rb b/app/workers/event_intake.rb
index 79be810..a4cbf67 100644
--- a/app/workers/event_intake.rb
+++ b/app/workers/event_intake.rb
@@ -5,11 +5,16 @@ class EventIntake
from_queue "worker.events"
def work(event_json)
- logger.info event_json
- json = JSON.parse(event_json)
- json['type'] = json['type'].capitalize
- event = Event.create!(json)
- logger.info("Create Event: #{event.id}")
+ logger.info(event_json)
+ Event.create!(to_hash(event_json))
ack!
end
+
+ private
+
+ def to_hash(json)
+ JSON.parse(json).tap do |event|
+ event['type'].capitalize!
+ end
+ end
end