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

Commit

Permalink
Merge 70a56f5 into 69e70ac
Browse files Browse the repository at this point in the history
  • Loading branch information
renatomassaro committed Oct 14, 2017
2 parents 69e70ac + 70a56f5 commit a10b24d
Show file tree
Hide file tree
Showing 61 changed files with 3,484 additions and 580 deletions.
31 changes: 10 additions & 21 deletions lib/account/websocket/channel/account.ex
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
defmodule Helix.Account.Websocket.Channel.Account do
import Helix.Websocket.Channel

channel Helix.Account.Websocket.Channel.Account do
@moduledoc """
Channel to notify an user of an action that affects them.
"""

use Phoenix.Channel

alias Helix.Websocket.Socket, as: Websocket

alias Helix.Account.Websocket.Channel.Account.Join, as: AccountJoin
alias Helix.Account.Websocket.Channel.Account.Requests.Bootstrap,
as: BootstrapRequest
alias Helix.Account.Websocket.Channel.Account.Requests.EmailReply,
as: EmailReplyRequest

def join(topic, _params, socket) do
request = AccountJoin.new(topic)
Websocket.handle_join(request, socket, &assign/3)
end
join _, AccountJoin

def handle_in("bootstrap", _params, socket) do
request = BootstrapRequest.new()
Websocket.handle_request(request, socket)
end
topic "bootstrap", BootstrapRequest

@doc """
Replies to a Storyline email.
Expand All @@ -37,13 +29,10 @@ defmodule Helix.Account.Websocket.Channel.Account do
- "reply_not_found" - The given reply ID is not valid, may be locked or not
exist within the current step email.
"""
def handle_in("email.reply", params, socket) do
request = EmailReplyRequest.new(params)
Websocket.handle_request(request, socket)
end
topic "email.reply", EmailReplyRequest

intercept ["event"]

def handle_out("event", event, socket),
do: Websocket.handle_event(event, socket, &push/3)
@doc """
Intercepts and handles outgoing events.
"""
event_handler "event"
end
38 changes: 17 additions & 21 deletions lib/account/websocket/channel/account/requests/bootstrap.ex
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
defmodule Helix.Account.Websocket.Channel.Account.Requests.Bootstrap do
import Helix.Websocket.Request

require Helix.Websocket.Request
request Helix.Account.Websocket.Channel.Account.Requests.Bootstrap do

Helix.Websocket.Request.register()
alias Helix.Account.Public.Account, as: AccountPublic

defimpl Helix.Websocket.Requestable do
def check_params(request, _socket),
do: reply_ok(request)

alias Helix.Websocket.Utils, as: WebsocketUtils
alias Helix.Account.Public.Account, as: AccountPublic
def check_permissions(request, _socket),
do: reply_ok(request)

def check_params(request, _socket),
do: {:ok, request}
def handle_request(request, socket) do
entity_id = socket.assigns.entity_id

def check_permissions(request, _socket),
do: {:ok, request}
meta = %{
bootstrap: AccountPublic.bootstrap(entity_id)
}

def handle_request(request, socket) do
entity_id = socket.assigns.entity_id

meta = %{bootstrap: AccountPublic.bootstrap(entity_id)}

{:ok, %{request| meta: meta}}
end
update_meta(request, meta, reply: true)
end

def reply(request, socket) do
data = AccountPublic.render_bootstrap(request.meta.bootstrap)
WebsocketUtils.reply_ok(data, socket)
end
render(request, _socket) do
data = AccountPublic.render_bootstrap(request.meta.bootstrap)
{:ok, data}
end
end
75 changes: 34 additions & 41 deletions lib/account/websocket/channel/account/requests/email_reply.ex
Original file line number Diff line number Diff line change
@@ -1,53 +1,46 @@
defmodule Helix.Account.Websocket.Channel.Account.Requests.EmailReply do
import Helix.Websocket.Request

request Helix.Account.Websocket.Channel.Account.Requests.EmailReply do
@moduledoc """
Implementation of the `EmailReply` request, which allows the player to send
an (storyline) email reply to the Contact (story character)
"""

require Helix.Websocket.Request

Helix.Websocket.Request.register()

defimpl Helix.Websocket.Requestable do

alias Helix.Websocket.Utils, as: WebsocketUtils
alias Helix.Story.Public.Story, as: StoryPublic
alias Helix.Story.Public.Story, as: StoryPublic

def check_params(request, _socket) do
with \
true <- is_binary(request.unsafe["reply_id"])
do
params = %{
reply_id: request.unsafe["reply_id"]
}
def check_params(request, _socket) do
with \
true <- is_binary(request.unsafe["reply_id"])
do
params = %{
reply_id: request.unsafe["reply_id"]
}

{:ok, %{request| params: params}}
else
_ ->
{:error, %{message: "bad_request"}}
end
update_params(request, params, reply: true)
else
_ ->
bad_request()
end
end

@doc """
Permissions whether that reply is valid within the player's current context
are checked at StoryPublic- and StoryAction-level
"""
def check_permissions(request, _socket),
do: {:ok, request}

def handle_request(request, socket) do
entity_id = socket.assigns.entity_id
reply_id = request.params.reply_id

case StoryPublic.send_reply(entity_id, reply_id) do
:ok ->
{:ok, request}
error ->
error
end
@doc """
Permissions whether that reply is valid within the player's current context
are checked at StoryPublic- and StoryAction-level
"""
def check_permissions(request, _socket),
do: reply_ok(request)

def handle_request(request, socket) do
entity_id = socket.assigns.entity_id
reply_id = request.params.reply_id

case StoryPublic.send_reply(entity_id, reply_id) do
:ok ->
reply_ok(request)
{:error, %{message: msg}} ->
reply_error(msg)
end

def reply(_request, socket),
do: WebsocketUtils.reply_ok(%{}, socket)
end

render_empty()
end
4 changes: 2 additions & 2 deletions lib/account/websocket/routes.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule Helix.Account.Websocket.Routes do

alias Helix.Websocket.Socket
alias Helix.Websocket
alias Helix.Account.Websocket.Controller.Account, as: AccountController

# Note that this is somewhat a hack to allow us to break our request-response
Expand All @@ -12,7 +12,7 @@ defmodule Helix.Account.Websocket.Routes do
def account_logout(socket) do
AccountController.logout(socket.assigns, %{})

socket_id = Socket.id(socket)
socket_id = Websocket.id(socket)
Helix.Endpoint.broadcast(socket_id, "disconnect", %{})

# Logout will blacklist the token and stop the socket, so, this only makes
Expand Down
2 changes: 1 addition & 1 deletion lib/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Helix.Endpoint do

require Helix.Appsignal

socket "/", Helix.Websocket.Socket
socket "/", Helix.Websocket

plug Corsica,
origins: Application.get_env(:helix, Helix.Endpoint)[:allowed_cors],
Expand Down
67 changes: 67 additions & 0 deletions lib/entity/henforcer/entity.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
defmodule Helix.Entity.Henforcer.Entity do

import Helix.Henforcer

alias Helix.Server.Model.Server
alias Helix.Server.Henforcer.Server, as: ServerHenforcer
alias Helix.Entity.Model.Entity
alias Helix.Entity.Query.Entity, as: EntityQuery

@type entity_exists_relay :: %{entity: Entity.t}
@type entity_exists_error ::
{false, {:entity, :not_found}, entity_exists_relay}

@spec entity_exists?(Entity.id) ::
{true, entity_exists_relay}
| entity_exists_error
@doc """
Henforces the given Entity exists.
"""
def entity_exists?(entity_id = %Entity.ID{}) do
with entity = %Entity{} <- EntityQuery.fetch(entity_id) do
reply_ok(relay(%{entity: entity}))
else
_ ->
reply_error({:entity, :not_found})
end
end

@type owns_server_relay :: %{entity: Entity.t, server: Server.t}
@type owns_server_relay_partial :: owns_server_relay

@type owns_server_error ::
{false, {:server, :not_belongs}, owns_server_relay_partial}
| entity_exists_error
| ServerHenforcer.server_exists_error

@spec owns_server?(Entity.idt, Server.idt) ::
{true, owns_server_relay}
| owns_server_error
@doc """
Henforces the Entity is the owner of the given server.
"""
def owns_server?(entity_id = %Entity.ID{}, server) do
henforce entity_exists?(entity_id) do
owns_server?(relay.entity, server)
end
end

def owns_server?(entity, server_id = %Server.ID{}) do
henforce(ServerHenforcer.server_exists?(server_id)) do
owns_server?(entity, relay.server)
end
end

def owns_server?(entity = %Entity{}, server = %Server{}) do
with \
owner = %Entity{} <- EntityQuery.fetch_by_server(server),
true <- owner == entity
do
reply_ok()
else
_ ->
reply_error({:server, :not_belongs})
end
|> wrap_relay(%{entity: entity, server: server})
end
end
55 changes: 46 additions & 9 deletions lib/hell/hell/hector.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule HELL.Hector do
defmodule Hector do
@moduledoc """
Hector is a helper to:
Expand Down Expand Up @@ -217,6 +217,22 @@ defmodule HELL.Hector do
result
end

defp format_str(sql) do
sql
|> String.replace("\n", " ") # Remove newlines
|> remove_extra_spaces()
end

defp remove_extra_spaces(sql) do
if String.contains?(sql, " ") do
sql
|> String.replace(" ", " ")
|> remove_extra_spaces()
else
sql
end
end

@spec query(String.t, [term], term) ::
{:ok, query :: String.t}
| {:error, reason :: term}
Expand All @@ -228,6 +244,7 @@ defmodule HELL.Hector do
def query(sql, params, caster \\ &std_caster/2) do
{first, splits} =
sql
|> format_str()
|> String.split("##")
|> List.pop_at(0)

Expand Down Expand Up @@ -273,6 +290,11 @@ defmodule HELL.Hector do
end
end

def query!(sql, params, caster \\ &std_caster/2) do
{:ok, query} = query(sql, params, caster)
query
end

@doc """
Hector default caster. It simply, naively and blindly ensures the given
value is a string. This does not protect you against potential attacks. Read
Expand Down Expand Up @@ -300,7 +322,11 @@ defmodule HELL.Hector do
columns = atomize_columns(result.columns)

Enum.map(result.rows, fn row ->
apply(repo, :load, [module, {columns, row}])
if :erlang.function_exported(module, :hector_loader, 2) do
apply(module, :hector_loader, [repo, {columns, row}])
else
apply(repo, :load, [module, {columns, row}])
end
end)
end

Expand Down Expand Up @@ -336,17 +362,28 @@ defmodule HELL.Hector do
end

defp get_type(type) do

next_parens = Enum.find_index(type, &(&1 == List.first(')')))
next_space = Enum.find_index(type, &(&1 == List.first(' ')))

cond do
next_parens != nil ->
Enum.split(type, next_parens)
next_space != nil ->
Enum.split(type, next_space)
true ->
next_split =
if is_integer(next_parens) and is_integer(next_space) do
Enum.min([next_parens] ++ [next_space])
else
cond do
next_parens ->
next_parens
next_space ->
next_space
true ->
:norest
end
end

case next_split do
:norest ->
{type, :norest}
split_index ->
Enum.split(type, split_index)
end
end
end
Loading

0 comments on commit a10b24d

Please sign in to comment.