Skip to content
This repository has been archived by the owner on Jun 11, 2023. It is now read-only.

Commit

Permalink
Merge cf550ad into d625f3c
Browse files Browse the repository at this point in the history
  • Loading branch information
renatomassaro committed Jul 29, 2018
2 parents d625f3c + cf550ad commit 11c9433
Show file tree
Hide file tree
Showing 57 changed files with 2,225 additions and 1,821 deletions.
13 changes: 2 additions & 11 deletions lib/event/dispatcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,10 @@ defmodule Helix.Event.Dispatcher do
##############################################################################

# All
event LogEvent.Forge.Processed
event LogEvent.Log.Created
event LogEvent.Log.Deleted
event LogEvent.Log.Modified
# event LogEvent.Log.Modified

##############################################################################
# Process events
Expand Down Expand Up @@ -209,8 +210,6 @@ defmodule Helix.Event.Dispatcher do
event SoftwareEvent.File.Transfer.Processed
event SoftwareEvent.Firewall.Started
event SoftwareEvent.Firewall.Stopped
event SoftwareEvent.LogForge.LogCreate.Processed
event SoftwareEvent.LogForge.LogEdit.Processed
event SoftwareEvent.Virus.Collect.Processed
event SoftwareEvent.Virus.Collected
event SoftwareEvent.Virus.Installed
Expand Down Expand Up @@ -249,14 +248,6 @@ defmodule Helix.Event.Dispatcher do
ProcessHandler.Cracker,
:firewall_stopped

event SoftwareEvent.LogForge.LogCreate.Processed,
LogHandler.Log,
:log_forge_conclusion

event SoftwareEvent.LogForge.LogEdit.Processed,
LogHandler.Log,
:log_forge_conclusion

event SoftwareEvent.Virus.Collect.Processed,
SoftwareHandler.Virus,
:handle_collect
Expand Down
102 changes: 74 additions & 28 deletions lib/event/loggable/flow.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ defmodule Helix.Event.Loggable.Flow do
alias Helix.Event
alias Helix.Event.Loggable.Utils, as: LoggableUtils
alias Helix.Entity.Model.Entity
alias Helix.Log.Model.Log
alias Helix.Log.Model.LogType
alias Helix.Log.Action.Log, as: LogAction
alias Helix.Network.Model.Bounce
alias Helix.Network.Model.Network
alias Helix.Network.Model.Tunnel
alias Helix.Network.Query.Bounce, as: BounceQuery
alias Helix.Server.Model.Server

@type log_entry ::
{Server.id, Entity.id, log_msg}

@type log_msg :: String.t
@typep log_entry ::
{Server.id, Entity.id, Log.info}

@doc """
Top-level macro for events wanting to implement the Loggable protocol.
Expand Down Expand Up @@ -66,13 +66,12 @@ defmodule Helix.Event.Loggable.Flow do
"""
defmacro log_map(map) do
quote do
map = unquote(map)
unquote(map)

# Put default values (if not specified)
map
|> Map.put_new(:network_id, nil)
|> Map.put_new(:endpoint_id, nil)
|> Map.put_new(:msg_endpoint, nil)
|> Map.put_new(:data_both, %{})
|> Map.put_new(:opts, %{})
end
end
Expand Down Expand Up @@ -119,8 +118,11 @@ defmodule Helix.Event.Loggable.Flow do
gateway_id: gateway_id,
endpoint_id: endpoint_id,
network_id: network_id,
msg_gateway: msg_gateway,
msg_endpoint: msg_endpoint,
type_gateway: type_gateway,
data_gateway: data_gateway,
type_endpoint: type_endpoint,
data_endpoint: data_endpoint,
data_both: data_both,
opts: opts
})
do
Expand All @@ -147,25 +149,36 @@ defmodule Helix.Event.Loggable.Flow do
end
|> customize_last_ip(opts)

msg_gateway = String.replace(msg_gateway, "$first_ip", first_ip)
msg_endpoint = String.replace(msg_endpoint, "$last_ip", last_ip)
data_gateway =
data_gateway
|> replace_ips(first_ip, last_ip)
|> Map.merge(data_both)

data_endpoint =
data_endpoint
|> replace_ips(first_ip, last_ip)
|> Map.merge(data_both)

log_gateway = build_entry(gateway_id, entity_id, msg_gateway)
log_endpoint = build_entry(endpoint_id, entity_id, msg_endpoint)
log_gateway = {type_gateway, LogType.new(type_gateway, data_gateway)}
log_endpoint = {type_endpoint, LogType.new(type_endpoint, data_endpoint)}

bounce_logs =
entry_gateway = build_entry(gateway_id, entity_id, log_gateway)
entry_endpoint = build_entry(endpoint_id, entity_id, log_endpoint)

bounce_entries =
if skip_bounce? do
[]
else
build_bounce_entries(
bounce,
{gateway_id, network_id, gateway_ip},
{endpoint_id, network_id, endpoint_ip},
entity_id
entity_id,
network_id
)
end

[log_gateway, log_endpoint, bounce_logs] |> List.flatten()
[entry_gateway, entry_endpoint, bounce_entries] |> List.flatten()
end

@doc """
Expand All @@ -178,10 +191,13 @@ defmodule Helix.Event.Loggable.Flow do
event: _,
server_id: server_id,
entity_id: entity_id,
msg_server: msg_server
type: type,
data: data
})
do
[build_entry(server_id, entity_id, msg_server)]
log_type = LogType.new(type, data)

[build_entry(server_id, entity_id, {type, log_type})]
end

@doc """
Expand Down Expand Up @@ -249,7 +265,7 @@ defmodule Helix.Event.Loggable.Flow do
defdelegate format_ip(ip),
to: LoggableUtils

@spec build_entry(Server.id, Entity.id, log_msg) ::
@spec build_entry(Server.id, Entity.id, Log.info) ::
log_entry
@doc """
Returns data required to insert the log
Expand All @@ -263,16 +279,23 @@ defmodule Helix.Event.Loggable.Flow do
Messages follow the format "Connection bounced from hop (n-1) to (n+1)"
"""
def build_bounce_entries(nil, _, _, _),
def build_bounce_entries(nil, _, _, _, _),
do: []
def build_bounce_entries(bounce_id = %Bounce.ID{}, gateway, endpoint, entity) do
def build_bounce_entries(
bounce_id = %Bounce.ID{}, gateway, endpoint, entity, network
) do
bounce_id
|> BounceQuery.fetch()
|> build_bounce_entries(gateway, endpoint, entity)
|> build_bounce_entries(gateway, endpoint, entity, network)
end

def build_bounce_entries(
bounce = %Bounce{}, gateway = {_, _, _}, endpoint = {_, _, _}, entity_id)
do
bounce = %Bounce{},
gateway = {_, _, _},
endpoint = {_, _, _},
entity_id,
network_id
) do
full_path = [gateway | bounce.links] ++ [endpoint]
length_hop = length(full_path)

Expand All @@ -298,8 +321,11 @@ defmodule Helix.Event.Loggable.Flow do
{_, _, ip_prev} = bounce_map[idx - 1]
{_, _, ip_next} = bounce_map[idx + 1]

msg = "Connection bounced from #{ip_prev} to #{ip_next}"
entry = build_entry(server_id, entity_id, msg)
data = %{ip_prev: ip_prev, ip_next: ip_next, network_id: network_id}
# TODO
log_type = {:connection_bounced, LogType.new(:connection_bounced, data)}

entry = build_entry(server_id, entity_id, log_type)

{idx + 1, acc ++ [entry]}
end
Expand All @@ -321,8 +347,8 @@ defmodule Helix.Event.Loggable.Flow do
do: save([log_entry])
def save(logs) do
logs
|> Enum.map(fn {server_id, entity_id, msg} ->
{:ok, _, events} = LogAction.create(server_id, entity_id, msg)
|> Enum.map(fn {server_id, entity_id, log_type} ->
{:ok, _, events} = LogAction.create(server_id, entity_id, log_type)
events
end)
|> List.flatten()
Expand Down Expand Up @@ -378,4 +404,24 @@ defmodule Helix.Event.Loggable.Flow do
do: censor_ip(ip)
defp customize_last_ip(ip, _),
do: ip

defp replace_ips(params, first_ip, last_ip) do
params
|> Enum.reduce([], fn {k, v}, acc ->
new_v =
case v do
"$first_ip" ->
first_ip

"$last_ip" ->
last_ip

_ ->
v
end

[{k, new_v} | acc]
end)
|> Enum.into(%{})
end
end
81 changes: 32 additions & 49 deletions lib/log/action/log.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,73 +25,56 @@ defmodule Helix.Log.Action.Log do
alias Helix.Log.Event.Log.Deleted, as: LogDeletedEvent
alias Helix.Log.Event.Log.Modified, as: LogModifiedEvent

@spec create(Server.idt, Entity.idt, String.t, pos_integer | nil) ::
@spec create(Server.id, Entity.id, Log.info, pos_integer | nil) ::
{:ok, Log.t, [LogCreatedEvent.t]}
| {:error, Ecto.Changeset.t}
| :error
@doc """
Creates a new log linked to `entity` on `server` with `message` as content.
Creates a new log linked to `entity` on `server` with `log_info` as content.
"""
def create(server, entity, message, forge \\ nil) do
with {:ok, log} <- LogInternal.create(server, entity, message, forge) do
event = LogCreatedEvent.new(log)
def create(server_id, entity_id, log_info, forge_version \\ nil) do
case LogInternal.create(server_id, entity_id, log_info, forge_version) do
{:ok, log} ->
{:ok, log, [LogCreatedEvent.new(log)]}

{:ok, log, [event]}
{:error, _} ->
:error
end
end

@spec revise(Log.t, Entity.idt, String.t, pos_integer) ::
{:ok, Log.t, [LogModifiedEvent.t]}
| {:error, Ecto.Changeset.t}
@spec revise(Log.t, Entity.id, Log.info, pos_integer) ::
{:ok, Log.t, [LogRevisedEvent.t]}
| :error
@doc """
Adds a revision over `log`.
### Params
- `entity` is the the entity that is doing the revision.
- `message` is the new log's content.
- `forge_version` is the version of log forger used to make this revision.
### Examples
iex> revise(%Log{}, %Entity{}, "empty log", 100)
{:ok, %Log{message: "empty log"}, [%LogModifiedEvent{}]}
Adds a revision to the given `log`.
"""
def revise(log, entity, message, forge_version) do
with \
{:ok, log} <- LogInternal.revise(log, entity, message, forge_version)
do
event = LogModifiedEvent.new(log)

{:ok, log, [event]}
def revise(log = %Log{}, entity_id, log_info, forge_version) do
case LogInternal.revise(log, entity_id, log_info, forge_version) do
{:ok, log} ->
event = LogRevisedEvent.new(log)
{:ok, log, [event]}

{:error, _} ->
:error
end
end

@spec recover(Log.t) ::
{:ok, :recovered, [LogModifiedEvent.t]}
| {:ok, :deleted, [LogDeletedEvent.t]}
| {:error, :original_revision}
{:ok, :destroyed, [LogDeletedEvent.t]}
| {:ok, :original, []}
| {:ok, :recovered, [LogRecoveredEvent.t]}
@doc """
Recovers `log` to a previous revision.
### Notes
- If the log is in its original state and it is not a forged log, the
operation will fail with `{:error, :original_revision}`.
- If the log is in its original state and it is forged, it will be deleted,
returning `{:ok, :deleted, [Helix.Event.t]}`.
- Otherwise the revision will be deleted and the log will be updated to use
the last revision's message, returning `{:ok, :recovered, [Helix.Event.t]}`.
Attempts to recover the given `log`.
"""
def recover(log) do
def recover(log = %Log{}) do
case LogInternal.recover(log) do
{:ok, :deleted} ->
event = LogDeletedEvent.new(log)
{:ok, :deleted, [event]}
:destroyed ->
{:ok, :destroyed, [LogDeletedEvent.new(log)]}

{:ok, :recovered} ->
event = LogModifiedEvent.new(log)
{:ok, :recovered, [event]}
{:original, _} ->
{:ok, :original, []}

{:error, :original_revision} ->
{:error, :original_revision}
{:recovered, new_log} ->
{:ok, :recovered, [LogRecoveredEvent.new(new_log)]}
end
end
end
52 changes: 52 additions & 0 deletions lib/log/event/forge.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule Helix.Log.Event.Forge do

import Helix.Event

event Processed do
@moduledoc """
`LogForgeProcessedEvent` is fired when the underlying LogForgeProcess has
achieved its objective and finished executing.
"""

alias Helix.Process.Model.Process
alias Helix.Log.Model.Log
alias Helix.Log.Process.Forge, as: LogForgeProcess

@type t ::
%__MODULE__{
action: LogForgeProcess.action,
server_id: Server.id,
entity_id: Entity.id,
target_log_id: Log.id | nil,
log_info: Log.info,
forger_version: pos_integer
}

event_struct [
:action,
:server_id,
:entity_id,
:target_log_id,
:log_info,
:forger_version
]

@spec new(Process.t, LogForgeProcess.t) ::
t
def new(process = %Process{}, data = %LogForgeProcess{}) do
%__MODULE__{
action: get_action(process),
server_id: process.target_id,
entity_id: process.source_entity_id,
target_log_id: process.tgt_log_id,
log_info: {data.log_type, data.log_data},
forger_version: data.forger_version
}
end

defp get_action(%Process{type: :log_forge_create}),
do: :create
defp get_action(%Process{type: :log_forge_edit}),
do: :edit
end
end
Loading

0 comments on commit 11c9433

Please sign in to comment.