Skip to content

Commit

Permalink
Merge pull request #142 from edgurgel/upgrade
Browse files Browse the repository at this point in the history
Upgrade
  • Loading branch information
Eduardo Gurgel authored Jul 13, 2019
2 parents 383b4ee + 44b834f commit aec120b
Show file tree
Hide file tree
Showing 57 changed files with 1,602 additions and 1,003 deletions.
9 changes: 9 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
inputs: [
"lib/**/*.{ex,exs}",
"test/**/*.{ex,exs}",
"mix.exs"
],

locals_without_parens: []
]
21 changes: 13 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
language: elixir

otp_release:
- 20.0
elixir:
- 1.5.1
cache:
directories:
- deps

matrix:
include:
- elixir: 1.9
otp_release: 21.0
- elixir: 1.9
otp_release: 22.0.1
sudo: false
env:
- MIX_ENV=test
env:
matrix:
- POXA_REGISTRY_ADAPTER=gproc
Expand All @@ -15,8 +19,9 @@ before_script:
- export PLT_FILENAME=elixir-$TRAVIS_ELIXIR_VERSION-$TRAVIS_OTP_RELEASE.plt
- wget -O .local.plt https://s3.amazonaws.com/poxa-plt/travis_elixir_plts/$PLT_FILENAME || true
script:
- MIX_ENV=test mix test --no-start --trace --exclude integration
- MIX_ENV=test mix test --trace --only integration
- mix test --no-start --trace
- mix test --trace --only integration
- mix format --check-formatted
- mix dialyzer -o dialyzer.out && cat dialyzer.out || true
after_script:
- PULL_REQUEST_ID=$TRAVIS_PULL_REQUEST pronto run -f github_pr -c origin/master
Expand Down
50 changes: 28 additions & 22 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
FROM elixir:1.5.2-alpine AS builder
# Based on https://github.com/hexpm/hexpm/blob/08e80ed4fe82b145f6cee1d01da16e162add2a56/Dockerfile
FROM elixir:1.9.0-alpine as build

ENV APP_NAME poxa
ENV MIX_ENV prod
ENV MIX_ENV=prod

RUN apk --no-cache add git erlang-xmerl erlang-crypto erlang-sasl
RUN mkdir /app
WORKDIR /app

COPY . /source
WORKDIR /source
RUN mix local.hex --force && mix local.rebar --force

RUN mix do \
local.hex --force, \
local.rebar --force, \
deps.get, \
compile
RUN echo "" > config/poxa.prod.conf
RUN mix release
RUN mkdir -p /app/$APP_NAME
WORKDIR /app/$APP_NAME
RUN tar xzf /source/_build/prod/rel/$APP_NAME/releases/*/$APP_NAME.tar.gz
# install mix dependencies
COPY mix.exs mix.lock ./
COPY config config
RUN mix deps.get
RUN mix deps.compile

# build project
COPY priv priv
COPY lib lib
RUN mix compile

FROM alpine:3.6
# build release
COPY rel rel
RUN mix release

ENV APP_NAME poxa
ENV MIX_ENV prod
# prepare release image
FROM alpine:3.9 AS app
RUN apk add --update bash openssl

RUN apk --no-cache add bash openssl
RUN mkdir /app
WORKDIR /app

COPY --from=builder /app /app
COPY --from=build /app/_build/prod/rel/poxa ./
RUN chown -R nobody: /app
USER nobody

CMD /app/$APP_NAME/bin/$APP_NAME foreground
ENV HOME=/app
CMD /app/bin/poxa start
66 changes: 40 additions & 26 deletions lib/poxa.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,45 @@ defmodule Poxa do
use Application
require Logger

@registry_adapter Poxa.Registry.adapter
@registry_adapter Poxa.Registry.adapter()

def registry, do: @registry_adapter

def start(_type, _args) do
dispatch = :cowboy_router.compile([
{:_, [ { '/ping', Poxa.PingHandler, [] },
{ '/console', Poxa.Console.WSHandler, [] },
{ '/', :cowboy_static, {:priv_file, :poxa, 'index.html'} },
{ '/static/[...]', :cowboy_static, {:priv_dir, :poxa, 'static'} },
{ '/apps/:app_id/events', Poxa.EventHandler, [] },
{ '/apps/:app_id/channels[/:channel_name]', Poxa.ChannelsHandler, [] },
{ '/apps/:app_id/channels/:channel_name/users', Poxa.UsersHandler, [] },
{ '/app/:app_key', Poxa.WebsocketHandler, [] } ] }
])
dispatch =
:cowboy_router.compile([
{:_,
[
{"/ping", Poxa.PingHandler, []},
{"/console", Poxa.Console.WSHandler, []},
{"/", :cowboy_static, {:priv_file, :poxa, 'index.html'}},
{"/static/[...]", :cowboy_static, {:priv_dir, :poxa, 'static'}},
{"/apps/:app_id/events", Poxa.EventHandler, []},
{"/apps/:app_id/channels[/:channel_name]", Poxa.ChannelsHandler, []},
{"/apps/:app_id/channels/:channel_name/users", Poxa.UsersHandler, []},
{"/app/:app_key", Poxa.WebsocketHandler, []}
]}
])

case load_config() do
{:ok, config} ->
Logger.info "Starting Poxa, app_id: #{config.app_id} on port #{config.port}"
{:ok, _} = :cowboy.start_http(:poxa, 100,
[port: config.port],
[env: [dispatch: dispatch]])
Logger.info("Starting Poxa, app_id: #{config.app_id} on port #{config.port}")

{:ok, _} =
:cowboy.start_clear(:poxa_http, [port: config.port], %{env: %{dispatch: dispatch}})

run_ssl(dispatch)
Poxa.Supervisor.start_link
Poxa.Supervisor.start_link()

:invalid_configuration ->
Logger.error "Error on start, set app_key, app_id and app_secret"
Logger.error("Error on start, set app_key, app_id and app_secret")
exit(:invalid_configuration)
end

end

def stop(_State) do
:ok = :cowboy.stop_listener(:poxa)
:ok = :cowboy.stop_listener(:poxa_http)
:ok = :cowboy.stop_listener(:poxa_https)
end

defp load_config do
Expand All @@ -47,9 +54,15 @@ defmodule Poxa do
{:ok, app_secret} = Application.fetch_env(:poxa, :app_secret)
{:ok, port} = Application.fetch_env(:poxa, :port)
{:ok, registry_adapter} = Application.fetch_env(:poxa, :registry_adapter)
{:ok, %{app_key: app_key, app_id: app_id,
app_secret: app_secret, port: to_integer(port),
registry_adapter: registry_adapter}}

{:ok,
%{
app_key: app_key,
app_id: app_id,
app_secret: app_secret,
port: to_integer(port),
registry_adapter: registry_adapter
}}
rescue
MatchError -> :invalid_configuration
end
Expand All @@ -63,14 +76,15 @@ defmodule Poxa do
{:ok, ssl_config} ->
if enabled_ssl?(ssl_config) do
ssl_port = Keyword.get(ssl_config, :port)
Logger.info "Starting Poxa using SSL on port #{ssl_port}"
Logger.info("Starting Poxa using SSL on port #{ssl_port}")
ssl_config = Keyword.drop(ssl_config, [:enabled])
{:ok, _} = :cowboy.start_https(:https, 100, ssl_config, [env: [dispatch: dispatch] ])
{:ok, _} = :cowboy.start_tls(:poxa_https, ssl_config, %{env: %{dispatch: dispatch}})
else
Logger.info "SSL not configured/started"
Logger.info("SSL not configured/started")
end

:error ->
Logger.info "SSL not configured/started"
Logger.info("SSL not configured/started")
end
end

Expand Down
15 changes: 11 additions & 4 deletions lib/poxa/adapter/gproc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,34 @@ defmodule Poxa.Adapter.GProc do
end

def subscription_count(channel, pid \\ :_)

def subscription_count(channel, pid) when is_pid(pid) or pid == :_ do
Ex2ms.fun do
{{:p, :l, {:pusher, ^channel}}, ^pid, _} -> true
end |> select_count
end
|> select_count
end

def subscription_count(channel, user_id) do
Ex2ms.fun do
{{:p, :l, {:pusher, ^channel}}, _, {^user_id, _}} -> true
end |> select_count
end
|> select_count
end

def subscriptions(pid) do
Ex2ms.fun do
{{:p, :l, {:pusher, channel}}, ^pid, {user_id, _}} -> [channel, user_id]
end |> select
end
|> select
end

def channels(pid \\ :_) do
Ex2ms.fun do
{{:p, :l, {:pusher, channel}}, ^pid, _} -> channel
end |> select |> Enum.uniq_by(&(&1))
end
|> select
|> Enum.uniq_by(& &1)
end

def unique_subscriptions(channel) do
Expand Down
4 changes: 3 additions & 1 deletion lib/poxa/auth_signature.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ defmodule Poxa.AuthSignature do
[app_key, remote_signed_data] ->
signed_data = sign_data(to_sign)
Poxa.Authentication.check_key(app_key) and signed_data == remote_signed_data
_ -> false

_ ->
false
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/poxa/authentication.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ defmodule Poxa.Authentication do
{:ok, app_key} = Application.fetch_env(:poxa, :app_key)
{:ok, secret} = Application.fetch_env(:poxa, :app_secret)

valid_body?(body, body_md5) and Signaturex.validate(app_key, secret, method, path, qs_vals, 600)
valid_body?(body, body_md5) and
Signaturex.validate(app_key, secret, method, path, qs_vals, 600)
end

@doc """
Expand All @@ -27,6 +28,7 @@ defmodule Poxa.Authentication do
end

defp valid_body?("", nil), do: true

defp valid_body?(body, body_md5) do
body_md5 == Poxa.CryptoHelper.md5_to_string(body)
end
Expand Down
12 changes: 7 additions & 5 deletions lib/poxa/authorization_helper.ex
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
defmodule Poxa.AuthorizationHelper do
alias Poxa.Authentication

@spec is_authorized(:cowboy_req.req, any) :: {true, :cowboy_req.req, any} | {{false, binary}, :cowboy_req.req, nil}
@spec is_authorized(:cowboy_req.req(), any) ::
{true, :cowboy_req.req(), any} | {{false, binary}, :cowboy_req.req(), nil}
def is_authorized(req, state) do
{:ok, body, req} = :cowboy_req.body(req)
{method, req} = :cowboy_req.method(req)
{qs_vals, req} = :cowboy_req.qs_vals(req)
{path, req} = :cowboy_req.path(req)
{:ok, body, req} = :cowboy_req.read_body(req)
method = :cowboy_req.method(req)
qs_vals = :cowboy_req.parse_qs(req)
path = :cowboy_req.path(req)

if Authentication.check(method, path, body, qs_vals) do
{true, req, state}
else
Expand Down
12 changes: 7 additions & 5 deletions lib/poxa/channel.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@ defmodule Poxa.Channel do
"""
def matches?(_, nil), do: false
def matches?(_, ""), do: false

def matches?(channel, prefix) do
base = byte_size(prefix)

case channel do
<<^prefix :: binary-size(base), _ :: binary>> -> true
<<^prefix::binary-size(base), _::binary>> -> true
_ -> false
end
end
Expand All @@ -95,19 +97,19 @@ defmodule Poxa.Channel do
Returns the list of channels the `pid` is subscribed
"""
@spec all(pid | :_) :: [binary]
def all(pid \\ :_), do: Poxa.registry.channels(pid)
def all(pid \\ :_), do: Poxa.registry().channels(pid)

@doc """
Returns a boolean indicating if the user identified by `identifier` is subscribed to the channel.
"""
@spec member?(binary, pid | :_ | PresenceSubscription.user_id) :: boolean
@spec member?(binary, pid | :_ | PresenceSubscription.user_id()) :: boolean
def member?(channel, identifier \\ :_), do: subscription_count(channel, identifier) != 0

@doc """
Returns how many connections are opened on the `channel`
"""
@spec subscription_count(binary, pid | :_ | PresenceSubscription.user_id) :: non_neg_integer
@spec subscription_count(binary, pid | :_ | PresenceSubscription.user_id()) :: non_neg_integer
def subscription_count(channel, pid \\ :_) do
Poxa.registry.subscription_count(channel, pid)
Poxa.registry().subscription_count(channel, pid)
end
end
Loading

0 comments on commit aec120b

Please sign in to comment.