• 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

77.5
/lib/supavisor/secret_checker.ex
1
defmodule Supavisor.SecretChecker do
2
  @moduledoc false
3

4
  use GenServer
5
  require Logger
6

7
  alias Supavisor.Helpers
8

9
  @interval :timer.seconds(15)
10

11
  def start_link(args) do
12
    name = {:via, Registry, {Supavisor.Registry.Tenants, {:secret_checker, args.id}}}
20✔
13

14
    GenServer.start_link(__MODULE__, args, name: name)
20✔
15
  end
16

17
  def init(args) do
18
    Logger.debug("SecretChecker: Starting secret checker")
20✔
19
    tenant = Supavisor.tenant(args.id)
20✔
20

21
    %{auth: auth, user: user} = Enum.find(args.replicas, fn e -> e.replica_type == :write end)
20✔
22

23
    state = %{
20✔
24
      tenant: tenant,
25
      auth: auth,
26
      user: user,
27
      key: {:secrets, tenant, user},
28
      ttl: args[:ttl] || :timer.hours(24),
20✔
29
      conn: nil,
30
      check_ref: check()
31
    }
32

33
    Logger.metadata(project: tenant, user: user)
20✔
34
    {:ok, state, {:continue, :init_conn}}
20✔
35
  end
36

37
  def handle_continue(:init_conn, %{auth: auth} = state) do
38
    ssl_opts =
20✔
39
      if auth.upstream_ssl and auth.upstream_verify == :peer do
20✔
40
        [
41
          verify: :verify_peer,
NEW
42
          cacerts: [Helpers.upstream_cert(auth.upstream_tls_ca)],
×
NEW
43
          server_name_indication: auth.host,
×
NEW
44
          customize_hostname_check: [{:match_fun, fn _, _ -> true end}]
×
45
        ]
46
      else
47
        [
48
          verify: :verify_none
49
        ]
50
      end
51

52
    {:ok, conn} =
20✔
53
      Postgrex.start_link(
54
        hostname: auth.host,
20✔
55
        port: auth.port,
20✔
56
        database: auth.database,
20✔
57
        password: auth.password.(),
20✔
58
        username: auth.user,
20✔
59
        parameters: [application_name: "Supavisor auth_query"],
60
        ssl: auth.upstream_ssl,
20✔
61
        socket_options: [
62
          auth.ip_version
20✔
63
        ],
64
        queue_target: 1_000,
65
        queue_interval: 5_000,
66
        ssl_opts: ssl_opts
67
      )
68

69
    # kill the postgrex connection if the current process exits unexpectedly
70
    Process.link(conn)
20✔
71
    {:noreply, %{state | conn: conn}}
72
  end
73

74
  def handle_info(:check, state) do
75
    check_secrets(state)
3✔
76
    {:noreply, %{state | check_ref: check()}}
77
  end
78

79
  def handle_info(msg, state) do
80
    Logger.error("Unexpected message: #{inspect(msg)}")
×
81
    {:noreply, state}
82
  end
83

84
  def terminate(_, state) do
85
    :gen_statem.stop(state.conn)
×
86
    :ok
87
  end
88

89
  def check(interval \\ @interval),
23✔
90
    do: Process.send_after(self(), :check, interval)
23✔
91

92
  def check_secrets(%{auth: auth, user: user, conn: conn} = state) do
93
    case Helpers.get_user_secret(conn, auth.auth_query, user) do
3✔
94
      {:ok, secret} ->
95
        method = if secret.digest == :md5, do: :auth_query_md5, else: :auth_query
2✔
96
        secrets = Map.put(secret, :alias, auth.alias)
2✔
97

98
        update_cache =
2✔
99
          case Cachex.get(Supavisor.Cache, state.key) do
2✔
100
            {:ok, {:cached, {_, {old_method, old_secrets}}}} ->
101
              method != old_method or secrets != old_secrets.()
2✔
102

103
            other ->
104
              Logger.error("Failed to get cache: #{inspect(other)}")
×
105
              true
106
          end
107

108
        if update_cache do
2✔
109
          Logger.info("Secrets changed or not present, updating cache")
×
110
          value = {:ok, {method, fn -> secrets end}}
×
111
          Cachex.put(Supavisor.Cache, state.key, {:cached, value}, expire: :timer.hours(24))
×
112
        end
113

114
      other ->
UNCOV
115
        Logger.error("Failed to get secret: #{inspect(other)}")
1✔
116
    end
117
  end
118
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