• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / supavisor / e5e7ebfe80dbec4965226225050d4ef5c8216e88-PR-605

21 Feb 2025 02:35PM UTC coverage: 45.973% (-0.03%) from 46.003%
e5e7ebfe80dbec4965226225050d4ef5c8216e88-PR-605

Pull #605

github

hauleth
fix: remaining SSL connections that need to set `verify_none` option
Pull Request #605: fix: remaining SSL connections that need to set `verify_none` option

2 of 9 new or added lines in 3 files covered. (22.22%)

267 existing lines in 26 files now uncovered.

959 of 2086 relevant lines covered (45.97%)

635.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.56
/lib/supavisor/handler_helpers.ex
1
defmodule Supavisor.HandlerHelpers do
2
  @moduledoc false
3

4
  alias Phoenix.PubSub
5

6
  require Supavisor.Protocol.Server, as: Server
7

8
  @spec sock_send(Supavisor.sock(), iodata()) :: :ok | {:error, term()}
9
  def sock_send({mod, sock}, data) do
10
    mod.send(sock, data)
11,810✔
11
  end
12

13
  @spec sock_close(Supavisor.sock() | nil | {any(), nil}) :: :ok | {:error, term()}
14
  def sock_close(nil), do: :ok
×
15
  def sock_close({_, nil}), do: :ok
×
16

17
  def sock_close({mod, sock}), do: mod.close(sock)
3✔
18

19
  @spec setopts(Supavisor.sock(), term()) :: :ok | {:error, term()}
20
  def setopts({mod, sock}, opts) do
21
    mod = if mod == :gen_tcp, do: :inet, else: mod
6,104✔
22
    mod.setopts(sock, opts)
6,104✔
23
  end
24

25
  @spec active_once(Supavisor.sock()) :: :ok | {:error, term}
26
  def active_once(sock), do: setopts(sock, active: :once)
4,651✔
27

28
  @spec activate(Supavisor.sock()) :: :ok | {:error, term}
29
  def activate(sock), do: setopts(sock, active: true)
1,453✔
30

31
  @spec try_ssl_handshake(Supavisor.tcp_sock(), boolean) ::
32
          {:ok, Supavisor.sock()} | {:error, term()}
33
  def try_ssl_handshake(sock, true) do
34
    case sock_send(sock, Server.ssl_request()) do
×
35
      :ok -> ssl_recv(sock)
×
36
      error -> error
×
37
    end
38
  end
39

40
  def try_ssl_handshake(sock, false), do: {:ok, sock}
×
41

42
  @spec ssl_recv(Supavisor.tcp_sock()) :: {:ok, Supavisor.ssl_sock()} | {:error, term}
43
  def ssl_recv({:gen_tcp, sock} = s) do
44
    case :gen_tcp.recv(sock, 1, 15_000) do
×
45
      {:ok, <<?S>>} -> ssl_connect(s)
×
46
      {:ok, <<?N>>} -> {:ok, s}
×
47
      {:error, _} = error -> error
×
48
    end
49
  end
50

51
  @spec ssl_connect(Supavisor.tcp_sock(), pos_integer) ::
52
          {:ok, Supavisor.ssl_sock()} | {:error, term}
53
  def ssl_connect({:gen_tcp, sock}, timeout \\ 5000) do
54
    opts = [verify: :verify_none]
×
55

56
    case :ssl.connect(sock, opts, timeout) do
×
57
      {:ok, ssl_sock} -> {:ok, {:ssl, ssl_sock}}
×
58
      {:error, reason} -> {:error, reason}
×
59
    end
60
  end
61

62
  @spec send_error(Supavisor.sock(), String.t(), String.t()) :: :ok | {:error, term()}
63
  def send_error(sock, code, message) do
UNCOV
64
    data = Server.error_message(code, message)
2✔
UNCOV
65
    sock_send(sock, data)
2✔
66
  end
67

68
  @spec try_get_sni(Supavisor.sock()) :: String.t() | nil
69
  def try_get_sni({:ssl, sock}) do
70
    case :ssl.connection_information(sock, [:sni_hostname]) do
×
71
      {:ok, [sni_hostname: sni]} -> List.to_string(sni)
×
72
      _ -> nil
×
73
    end
74
  end
75

76
  def try_get_sni(_), do: nil
177✔
77

78
  @spec parse_user_info(map) ::
79
          {:cluster | :single, {String.t() | nil, String.t(), String.t() | nil}}
UNCOV
80
  def parse_user_info(%{"user" => user, "options" => %{"reference" => ref}} = payload) do
1✔
81
    # TODO: parse ref for cluster
82
    {:single, {user, ref, payload["database"]}}
83
  end
84

85
  def parse_user_info(%{"user" => user} = payload) do
86
    db_name = payload["database"]
183✔
87

88
    case :binary.split(user, ".cluster.") do
183✔
89
      [user] ->
90
        case :binary.matches(user, ".") do
182✔
UNCOV
91
          [] ->
2✔
92
            {:single, {user, nil, db_name}}
93

94
          matches ->
95
            {pos, 1} = List.last(matches)
180✔
96
            <<name::size(pos)-binary, ?., external_id::binary>> = user
180✔
97
            {:single, {name, external_id, db_name}}
98
        end
99

UNCOV
100
      [user, tenant] ->
1✔
101
        {:cluster, {user, tenant, db_name}}
102
    end
103
  end
104

105
  @spec send_cancel_query(non_neg_integer, non_neg_integer, term) :: :ok | {:errr, term}
106
  def send_cancel_query(pid, key, msg \\ :cancel_query) do
107
    PubSub.broadcast(
21✔
108
      Supavisor.PubSub,
109
      "cancel_req:#{pid}_#{key}",
21✔
110
      msg
111
    )
112
  end
113

114
  @spec listen_cancel_query(non_neg_integer, non_neg_integer) :: :ok | {:errr, term}
115
  def listen_cancel_query(pid, key) do
116
    PubSub.subscribe(Supavisor.PubSub, "cancel_req:#{pid}_#{key}")
171✔
117
  end
118

119
  @spec cancel_query(keyword, non_neg_integer, atom, non_neg_integer, non_neg_integer) :: :ok
120
  def cancel_query(host, port, ip_version, pid, key) do
121
    msg = Server.cancel_message(pid, key)
3✔
122
    opts = [:binary, {:packet, :raw}, {:active, true}, ip_version]
3✔
123
    {:ok, sock} = :gen_tcp.connect(host, port, opts)
3✔
124
    sock = {:gen_tcp, sock}
3✔
125
    :ok = sock_send(sock, msg)
3✔
126
    :ok = sock_close(sock)
3✔
127
  end
128

129
  @doc """
130
  Takes an allow list of CIDR ranges and filtres them for ranges which contain the address
131
  to test.
132

133
  If the IP address of the socket is not found an empty list is returned.
134

135
  ## Examples
136

137
    iex> Supavisor.HandlerHelpers.filter_cidrs(["0.0.0.0/0", "::/0"], {127, 0, 0, 1})
138
    ["0.0.0.0/0"]
139

140
    iex> Supavisor.HandlerHelpers.filter_cidrs(["71.209.249.38/32"], {71, 209, 249, 39})
141
    []
142

143
    iex> Supavisor.HandlerHelpers.filter_cidrs(["0.0.0.0/0", "::/0"], {8193, 3512, 34211, 0, 0, 35374, 880, 29492})
144
    ["::/0"]
145

146
    iex> Supavisor.HandlerHelpers.filter_cidrs(["0.0.0.0/0", "::/0"], :error)
147
    []
148

149
  """
150

151
  @spec filter_cidrs(list(), :inet.ip_address() | any()) :: list()
152
  def filter_cidrs(allow_list, addr) when is_list(allow_list) and is_tuple(addr) do
153
    for range <- allow_list,
180✔
154
        range |> InetCidr.parse_cidr!() |> InetCidr.contains?(addr) do
155
      range
156
    end
157
  end
158

UNCOV
159
  def filter_cidrs(allow_list, _addr) when is_list(allow_list) do
1✔
160
    []
161
  end
162

163
  @spec addr_from_sock(Supavisor.sock()) :: {:ok, :inet.ip_address()} | :error
164
  def addr_from_sock({:gen_tcp, port}) do
165
    case :inet.peername(port) do
177✔
166
      {:ok, {:local, _}} ->
×
167
        :error
168

169
      {:ok, {:undefined, _}} ->
×
170
        :error
171

172
      {:ok, {:unspec, _}} ->
×
173
        :error
174

175
      {:ok, {addr, _port}} ->
177✔
176
        {:ok, addr}
177

178
      {:error, _} ->
×
179
        :error
180
    end
181
  end
182

183
  def addr_from_sock({:ssl, port}) do
184
    case :ssl.peername(port) do
×
185
      {:ok, {addr, _port}} ->
×
186
        {:ok, addr}
187

188
      {:error, _} ->
×
189
        :error
190
    end
191
  end
192
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc