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

Commit

Permalink
Merge pull request #378 from renatomassaro/bounce
Browse files Browse the repository at this point in the history
Add proper bounce support
  • Loading branch information
renatomassaro committed Jan 29, 2018
2 parents 6e253c9 + 42d7049 commit f40c095
Show file tree
Hide file tree
Showing 123 changed files with 6,546 additions and 1,367 deletions.
14 changes: 14 additions & 0 deletions events.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@
"Connection.Started",
"Process.Created"
],
"Network.Bounce": [
"Network.Bounce.Created",
"Network.Bounce.CreateFailed",
"Network.Bounce.Removed",
"Network.Bounce.RemoveFailed",
"Network.Bounce.Updated",
"Network.Bounce.UpdateFailed"
],
"Software.File.Transfer": [
"Connection.Started",
"Process.Created"
Expand Down Expand Up @@ -165,6 +173,12 @@
"Log.Created",
"Log.Modified",
"Log.Deleted",
"Network.Bounce.Created",
"Network.Bounce.CreateFailed",
"Network.Bounce.Removed",
"Network.Bounce.RemoveFailed",
"Network.Bounce.Updated",
"Network.Bounce.UpdateFailed",
"Server.Password.Acquired",
"Process.Created",
"Process.Completed",
Expand Down
17 changes: 13 additions & 4 deletions lib/account/public/index.ex
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
defmodule Helix.Account.Public.Index do

alias Helix.Client.Renderer, as: ClientRenderer
alias Helix.Entity.Model.Entity
alias Helix.Entity.Query.Entity, as: EntityQuery
alias Helix.Network.Model.Bounce
alias Helix.Network.Query.Bounce, as: BounceQuery
alias Helix.Server.Model.Server
alias Helix.Account.Public.Index.Inventory, as: InventoryIndex

@type index ::
%{
mainframe: Server.id,
inventory: InventoryIndex.index
inventory: InventoryIndex.index,
bounces: [Bounce.t]
}

@type rendered_index ::
%{
mainframe: String.t,
inventory: InventoryIndex.rendered_index
inventory: InventoryIndex.rendered_index,
bounces: [ClientRenderer.rendered_bounce]
}

@spec index(Entity.t) ::
Expand All @@ -26,9 +31,12 @@ defmodule Helix.Account.Public.Index do
|> Enum.reverse()
|> List.first()

bounces = BounceQuery.get_by_entity(entity)

%{
mainframe: mainframe,
inventory: InventoryIndex.index(entity)
inventory: InventoryIndex.index(entity),
bounces: bounces
}
end

Expand All @@ -37,7 +45,8 @@ defmodule Helix.Account.Public.Index do
def render_index(index) do
%{
mainframe: to_string(index.mainframe),
inventory: InventoryIndex.render_index(index.inventory)
inventory: InventoryIndex.render_index(index.inventory),
bounces: Enum.map(index.bounces, &ClientRenderer.render_bounce/1)
}
end
end
107 changes: 105 additions & 2 deletions lib/account/websocket/channel/account.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ channel Helix.Account.Websocket.Channel.Account do
alias Helix.Account.Websocket.Requests.EmailReply, as: EmailReplyRequest
alias Helix.Account.Websocket.Requests.Logout, as: LogoutRequest
alias Helix.Client.Websocket.Requests.Setup, as: ClientSetupProxyRequest
alias Helix.Network.Websocket.Requests.Bounce.Create, as: BounceCreateRequest
alias Helix.Network.Websocket.Requests.Bounce.Update, as: BounceUpdateRequest
alias Helix.Network.Websocket.Requests.Bounce.Remove, as: BounceRemoveRequest

@doc """
Joins the Account channel.
Expand All @@ -21,7 +24,7 @@ channel Helix.Account.Websocket.Channel.Account do
Errors:
- access_denied: Trying to connect to an account that isn't the one
authenticated on the socket.
+ base_errors
+ base errors
"""
join _, AccountJoin

Expand Down Expand Up @@ -49,7 +52,7 @@ channel Helix.Account.Websocket.Channel.Account do
Errors:
- "request_not_implemented_for_client" - The registered client does not
implements that request.
+ base_errors
+ base errors
"""
topic "client.setup", ClientSetupProxyRequest

Expand Down Expand Up @@ -82,6 +85,106 @@ channel Helix.Account.Websocket.Channel.Account do
"""
topic "account.logout", LogoutRequest

@doc """
Creates a new bounce.
Params:
*name: Bounce name.
*links: Links that will exist on the bounce. The received order will be the
bounce order. Must contain `network_id`, `ip` and `password`.
Example:
%{
"name" => "bounce_name",
"links" => [
%{"network_id" => "::", "ip" => "1.2.3.4", "password" => "hunter2"},
%{"network_id" => "::", "ip" => "4.3.2.1", "password" => "*******"}
]
}
Returns: :ok
Events:
- bounce_created: Emitted when bounce creation is successful
- bounce_create_failed: Emitted when bounce creation failed for any reason.
Errors:
Henforcer:
- nip_not_found: One of the entries of `links` was not found
- bounce_no_access: One of the entries of `links` failed to authenticate
Input validation:
- bad_link: One of the entries of `links` has an invalid format.
+ base errors
"""
topic "bounce.create", BounceCreateRequest

@doc """
Updates an existing bounce.
Params:
*bounce_id: Which bounce to update. Duh.
name: Set a new name for the bounce.
links: Set a new group of links that will be used for future bounces. Same
type as the one at "bounce.create".
NOTE: `name` and `links` are optional, but AT LEAST ONE of them must be set!
Example:
%{
"bounce_id" => "::1",
"name" => "new_name",
"links" => [
%{"network_id" => "::", "ip" => "8.8.8.8", "password" => "googol"}
]
}
Returns: :ok
Events:
- bounce_updated: Emitted when bounce update was successful.
- bounce_update_failed: Emitted when bounce update failed for any reason.
Errors:
Henforcer:
- bounce_not_belongs: Attempting to update a bounce that is not owned by you
- nip_not_found: One of the entries of `links` was not found
- bounce_no_access: One of the entries of `links` failed to authenticate
- bounce_in_use: Bounce is currently in use. All tunnels using the bounce must
be closed in order for it to be able to update its links.
Input validation:
- bad_link
"""
topic "bounce.update", BounceUpdateRequest

@doc """
Removes an existing bounce.
Params:
*bounce_id: Which bounce to remove
Returns: :ok
Events:
- bounce_removed: Emitted when bounce remove was successful.
- bounce_remove_failed: Emitted when bounce remove failed for any reason.
Errors:
Henforcer:
- bounce_not_belongs: Attempting to update a bounce that is not owned by you
- bounce_in_use: Bounce is currently in use. All tunnels using the bounce must
be closed in order for it to be able to update its links.
Input:
+ base errors
"""
topic "bounce.remove", BounceRemoveRequest

@doc """
Intercepts and handles outgoing events.
"""
Expand Down
9 changes: 9 additions & 0 deletions lib/client/renderer.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Helix.Client.Renderer do

alias Helix.Client.Renderer.Network, as: NetworkRenderer

@type rendered_bounce :: NetworkRenderer.rendered_bounce

defdelegate render_bounce(bounce),
to: NetworkRenderer
end
30 changes: 30 additions & 0 deletions lib/client/renderer/network.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule Helix.Client.Renderer.Network do

alias HELL.ClientUtils
alias HELL.HETypes
alias Helix.Network.Model.Bounce

@type rendered_bounce ::
%{
bounce_id: String.t,
name: String.t,
links: [HETypes.client_nip]
}

@spec render_bounce(Bounce.t) ::
rendered_bounce
def render_bounce(bounce = %Bounce{}) do
links =
bounce.links
|> Enum.map(fn {_, network_id, ip} ->
{network_id, ip}
end)
|> Enum.map(&ClientUtils.to_nip/1)

%{
bounce_id: to_string(bounce.bounce_id),
name: bounce.name,
links: links
}
end
end
15 changes: 12 additions & 3 deletions lib/core/validator/validator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ defmodule Helix.Core.Validator do
@type input_type ::
:password
| :hostname
| :bounce_name

@regex_hostname ~r/^[a-zA-Z0-9-_.@#]{1,20}$/

Expand All @@ -19,13 +20,15 @@ defmodule Helix.Core.Validator do
"""
def validate_input(input, type, opts \\ [])

def validate_input(input, :password, _) do
{:ok, input} # Validation itself is TODO :-)
end
def validate_input(input, :password, _),
do: validate_password(input)

def validate_input(input, :hostname, _),
do: validate_hostname(input)

def validate_input(input, :bounce_name, _),
do: validate_bounce_name(input)

defp validate_hostname(v) when not is_binary(v),
do: :error
defp validate_hostname(v) do
Expand All @@ -35,4 +38,10 @@ defmodule Helix.Core.Validator do
:error
end
end

def validate_password(input),
do: validate_hostname(input) # TODO

defp validate_bounce_name(v),
do: validate_hostname(v) # TODO
end
40 changes: 38 additions & 2 deletions lib/entity/henforcer/entity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ defmodule Helix.Entity.Henforcer.Entity do
import Helix.Henforcer

alias Helix.Cache.Query.Cache, as: CacheQuery
alias Helix.Network.Henforcer.Bounce, as: BounceHenforcer
alias Helix.Network.Model.Bounce
alias Helix.Network.Model.Network
alias Helix.Network.Query.Network, as: NetworkQuery
alias Helix.Software.Henforcer.Storage, as: StorageHenforcer
alias Helix.Software.Model.Storage
alias Helix.Server.Model.Component
alias Helix.Server.Model.Server
alias Helix.Server.Henforcer.Component, as: ComponentHenforcer
alias Helix.Server.Henforcer.Server, as: ServerHenforcer
alias Helix.Server.Model.Component
alias Helix.Server.Model.Server
alias Helix.Server.Query.Component, as: ComponentQuery
alias Helix.Entity.Model.Entity
alias Helix.Entity.Query.Entity, as: EntityQuery
Expand Down Expand Up @@ -199,4 +201,38 @@ defmodule Helix.Entity.Henforcer.Entity do
henforce_else(owns_server?(entity, server_id), {:storage, :not_belongs})
|> wrap_relay(%{entity: entity, storage: storage})
end

@type owns_bounce_relay :: %{entity: Entity.t, bounce: Bounce.t}
@type owns_bounce_relay_partial :: map
@type owns_bounce_error ::
{false, {:bounce, :not_belongs}, owns_bounce_relay_partial}
| entity_exists_error
| BounceHenforcer.bounce_exists_error

@spec owns_bounce?(Entity.idt, Bounce.idt) ::
{true, owns_bounce_relay}
| owns_bounce_error
@doc """
Henforces the Entity is the owner of the given Bounce.
"""
def owns_bounce?(entity_id = %Entity.ID{}, bounce) do
henforce entity_exists?(entity_id) do
owns_bounce?(relay.entity, bounce)
end
end

def owns_bounce?(entity, bounce_id = %Bounce.ID{}) do
henforce BounceHenforcer.bounce_exists?(bounce_id) do
owns_bounce?(entity, relay.bounce)
end
end

def owns_bounce?(entity = %Entity{}, bounce = %Bounce{}) do
if bounce.entity_id == entity.entity_id do
reply_ok()
else
reply_error({:bounce, :not_belongs})
end
|> wrap_relay(%{entity: entity, bounce: bounce})
end
end
8 changes: 8 additions & 0 deletions lib/entity/query/entity.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
defmodule Helix.Entity.Query.Entity do

alias Helix.Account.Model.Account
alias Helix.Network.Query.Bounce, as: BounceQuery
alias Helix.Network.Query.Network, as: NetworkQuery
alias Helix.Server.Model.Server
alias Helix.Universe.NPC.Model.NPC
Expand Down Expand Up @@ -58,6 +59,13 @@ defmodule Helix.Entity.Query.Entity do
defdelegate get_components(entity),
to: EntityInternal

@doc """
Returns all bounces owned by the entity.
"""
defdelegate get_bounces(entity),
to: BounceQuery,
as: :get_by_entity

@doc """
Returns all network connections owned by the entity.
"""
Expand Down
6 changes: 6 additions & 0 deletions lib/event/dispatcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ defmodule Helix.Event.Dispatcher do
##############################################################################

# All
event NetworkEvent.Bounce.Created
event NetworkEvent.Bounce.CreateFailed
event NetworkEvent.Bounce.Removed
event NetworkEvent.Bounce.RemoveFailed
event NetworkEvent.Bounce.Updated
event NetworkEvent.Bounce.UpdateFailed
event NetworkEvent.Connection.Closed
event NetworkEvent.Connection.Started

Expand Down
Loading

0 comments on commit f40c095

Please sign in to comment.