-
-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: use simple_connection for auth_query #342
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.1.55 | ||
1.1.56 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
defmodule Supavisor.SingleConnection do | ||
require Logger | ||
@behaviour Postgrex.SimpleConnection | ||
|
||
def connect(conf), do: Postgrex.SimpleConnection.start_link(__MODULE__, conf, conf) | ||
|
||
@impl true | ||
def init(args) do | ||
Logger.debug("init args: #{inspect(args, pretty: true)}") | ||
Process.monitor(args[:caller]) | ||
# put the hostname in the process dictionary to be able to find it in an emergency | ||
Process.put(:auth_host, args[:hostname]) | ||
{:ok, %{from: nil, caller: args[:caller]}} | ||
end | ||
|
||
@impl true | ||
def handle_call({:query, query}, from, state), do: {:query, query, %{state | from: from}} | ||
|
||
def handle_result(results, state) when is_list(results) do | ||
result = | ||
case results do | ||
[%Postgrex.Result{} = res] -> res | ||
other -> other | ||
end | ||
|
||
Postgrex.SimpleConnection.reply(state.from, result) | ||
{:noreply, state} | ||
end | ||
|
||
@impl true | ||
def handle_result(%Postgrex.Error{} = error, state) do | ||
Postgrex.SimpleConnection.reply(state.from, error) | ||
{:noreply, state} | ||
end | ||
|
||
@impl true | ||
def handle_info({:DOWN, _, _, caller, _}, %{caller: caller} = state) do | ||
Logger.notice("Caller #{inspect(caller)} is down") | ||
{:stop, state} | ||
end | ||
|
||
def handle_info(msg, state) do | ||
Logger.error("Undefined message #{inspect(msg, pretty: true)}") | ||
{:noreply, state} | ||
end | ||
|
||
@impl true | ||
def notify(_, _, _), do: :ok | ||
end |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,36 @@ | ||||||||||||||
defmodule Supavisor.Integration.SingleConnectionTest do | ||||||||||||||
require Logger | ||||||||||||||
use Supavisor.DataCase, async: true | ||||||||||||||
alias Postgrex, as: P | ||||||||||||||
|
||||||||||||||
@tenant "proxy_tenant1" | ||||||||||||||
|
||||||||||||||
test "connects to database and executes a simple query" do | ||||||||||||||
db_conf = Application.get_env(:supavisor, Repo) | ||||||||||||||
|
||||||||||||||
args = [ | ||||||||||||||
hostname: db_conf[:hostname], | ||||||||||||||
port: Application.get_env(:supavisor, :proxy_port_transaction), | ||||||||||||||
database: "postgres", | ||||||||||||||
password: db_conf[:password], | ||||||||||||||
username: "transaction.#{@tenant}" | ||||||||||||||
] | ||||||||||||||
|
||||||||||||||
spawn(fn -> | ||||||||||||||
{:ok, pid} = | ||||||||||||||
args | ||||||||||||||
|> Keyword.put_new(:caller, self()) | ||||||||||||||
|> Supavisor.SingleConnection.connect() | ||||||||||||||
|
||||||||||||||
assert %Postgrex.Result{rows: [["1"]]} = | ||||||||||||||
Postgrex.SimpleConnection.call(pid, {:query, "SELECT 1"}) | ||||||||||||||
end) | ||||||||||||||
|
||||||||||||||
:timer.sleep(250) | ||||||||||||||
|
||||||||||||||
# check that the connection dies after the caller dies | ||||||||||||||
assert Enum.filter(Process.list(), fn pid -> | ||||||||||||||
Process.info(pid)[:dictionary][:auth_host] == db_conf[:hostname] | ||||||||||||||
end) == [] | ||||||||||||||
Comment on lines
+32
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For what is worth, using filter for this test has a tiny benefit that it shows the left side with the failed PIDs in exception reports. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True. That indeed may be useful. |
||||||||||||||
end | ||||||||||||||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@filipecabaco wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that instead we should reject
user
if these characters are present instead of just pretending that these do not exists.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already have a check for invalid characters during connection, but it only checks for slashes. I added this sanitization as an additional guard. It might be worth applying the same rule (
a-zA-Z0-9_
) during connection as wellsupavisor/lib/supavisor/client_handler.ex
Lines 157 to 164 in 61b629d