Packages
potionx
0.6.1
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.1.1
0.1.0
Potionx is a set of generators and functions that speeds up the process of setting up and deploying a full-stack application that uses Elixir with GraphQL for the server-side component and Vue for the frontend component.
Current section
Files
Jump to
Current section
Files
lib/potionx/auth/auth_plug.ex
defmodule Potionx.Plug.Auth do
@behaviour Plug
alias Potionx.Context.Service
def call(%{assigns: %{context: %Service{}}} = conn, opts) do
conn
|> Plug.Conn.fetch_cookies(
signed: Enum.map(Map.values(Potionx.Auth.token_config()), &(&1.name))
)
|> maybe_renew(opts)
|> fetch_session_from_conn(opts)
end
def fetch_session_from_conn(%{halted: true} = conn, _), do: conn
def fetch_session_from_conn(%{assigns: %{context: ctx}} = conn, %{session_service: session_service}) do
cookie_name = Potionx.Auth.token_config.access_token.name
conn
|> case do
%{cookies: %{^cookie_name => token}} ->
session_service.one_from_cache(
%Service{
filters: Map.put(%{}, :uuid_access, token)
}
)
_ ->
{:error, "no_cookie"}
end
|> case do
%{id: _} = session ->
conn
|> Plug.Conn.assign(
:context, %{
ctx |
roles: (Map.get(session, :user) || %{roles: nil}).roles,
session: session,
user: session.user
}
)
_ ->
conn
end
end
def init(opts) do
if !Keyword.get(opts, :session_service) do
raise "Potionx.Auth.Plug requires a session service"
end
Keyword.merge(
[
session_service: false
],
opts
)
|> Enum.into(%{})
end
def maybe_renew(conn, opts) do
cookie_name_access = Potionx.Auth.token_config.access_token.name
cookie_name_renewal = Potionx.Auth.token_config.renewal_token.name
conn
|> case do
%{cookies: %{^cookie_name_access => _}} ->
conn
%{cookies: %{^cookie_name_renewal => token}} ->
renew_or_halt(conn, token, opts)
_ ->
conn
end
end
def renew_or_halt(conn, token, %{session_service: session_service}) do
session_service.patch(
%Service{
changes: %{
ttl_access_seconds: Potionx.Auth.token_config().access_token.ttl_seconds,
uuid_access: Ecto.UUID.generate(),
uuid_renewal: Ecto.UUID.generate(),
ttl_renewal_seconds: Potionx.Auth.token_config().renewal_token.ttl_seconds
},
filters: %{
uuid_renewal: token
}
}
)
|> case do
{:ok, %{session_patch: session}} ->
Potionx.Auth.handle_user_session_cookies(
session,
conn
)
_err ->
conn
|> Plug.Conn.assign(:potionx_auth_error, "session_renew_error")
|> Plug.Conn.put_status(401)
|> Plug.Conn.halt
end
end
end