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

CaptainFact / captain-fact-api / bfa42cdaf8517a74dc136b9825f471c7c5a6301b

21 Dec 2025 05:57PM UTC coverage: 51.815% (-0.2%) from 51.976%
bfa42cdaf8517a74dc136b9825f471c7c5a6301b

push

github

web-flow
chore: Fix compilation warnings (#502)

* chore: Fix compilation warnings

* fix sources fetcher

5 of 16 new or added lines in 11 files covered. (31.25%)

8 existing lines in 8 files now uncovered.

1142 of 2204 relevant lines covered (51.81%)

14.32 hits per line

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

20.83
/apps/cf_rest_api/lib/controllers/auth_controller.ex
1
defmodule CF.RestApi.AuthController do
2
  @moduledoc """
3
  Manages identity and third party authentication.
4
  """
5

6
  use CF.RestApi, :controller
7
  require Logger
8

9
  alias CF.Authenticator
10
  alias CF.Authenticator.GuardianImpl
11
  alias CF.RestApi.{ErrorView, UserView, AuthController}
12

13
  alias Kaur.Result
14

15
  plug(
16
    Guardian.Plug.EnsureAuthenticated,
17
    [handler: AuthController]
18
    when action in [:logout, :unlink_provider]
19
  )
20

21
  @err_authentication_failed "authentication_failed"
22
  @err_invalid_email_password "invalid_email_password"
23

24
  @doc """
25
  Handle authentication callback for identity or OAuth providers
26
  """
27
  def callback(conn, %{"provider" => "identity", "email" => email, "password" => password}) do
28
    case Authenticator.get_user_for_email_or_name_password(email, password) do
4✔
29
      nil ->
30
        conn
31
        |> put_status(:unauthorized)
32
        |> put_view(ErrorView)
33
        |> render("error.json", message: @err_invalid_email_password)
2✔
34

35
      user ->
36
        signin_user(conn, user)
2✔
37
    end
38
  end
39

NEW
40
  def callback(_conn, %{"provider" => provider}) when provider in ["facebook"] do
×
41
    # This will be handled by the OAuth callback below
42
  end
43

44
  def callback(conn, params = %{"provider" => provider_str, "code" => code}) do
45
    user = GuardianImpl.Plug.current_resource(conn)
×
46
    provider = provider_atom!(provider_str)
×
47

48
    result =
×
49
      if user != nil do
50
        Authenticator.associate_user_with_third_party(user, provider, code)
×
51
      else
52
        Authenticator.get_user_by_third_party!(provider, code, params["invitation_token"])
×
53
      end
54

55
    case result do
×
56
      {:error, message} ->
57
        conn
58
        |> put_status(:unauthorized)
59
        |> put_view(ErrorView)
60
        |> render("error.json", message: message)
×
61

62
      user ->
63
        signin_user(conn, user)
×
64
    end
65
  end
66

67
  @doc """
68
  Unlink given provider from user's account
69
  """
70
  def unlink_provider(conn, %{"provider" => provider_str}) do
71
    user = GuardianImpl.Plug.current_resource(conn)
×
72
    provider = provider_atom!(provider_str)
×
73

74
    Authenticator.dissociate_third_party(user, provider)
75
    |> Result.and_then(fn updated_user ->
×
76
      conn
77
      |> put_view(UserView)
78
      |> render(:show, user: updated_user)
×
79
    end)
80
  end
81

82
  @doc """
83
  Logout user
84
  """
85
  def logout(conn, _params) do
86
    conn
87
    |> GuardianImpl.Plug.current_token()
88
    |> GuardianImpl.revoke()
×
89

90
    send_resp(conn, 204, "")
×
91
  end
92

93
  # Guardian methods: render errors on unauthenticated / unauthorized
94

95
  def unauthenticated(conn, _params) do
96
    conn
97
    |> put_status(:unauthorized)
98
    |> put_view(ErrorView)
99
    |> render("401.json")
×
100
  end
101

102
  def unauthorized(conn, _params) do
103
    conn
104
    |> put_status(:forbidden)
105
    |> put_view(ErrorView)
106
    |> render("403.json")
×
107
  end
108

109
  # ---- Private ----
110

111
  # [!] Must be called ONLY if all verifications (password, third party...)
112
  # have already been made.
113
  # Render a user_with token `%{user, token}`
114
  defp signin_user(conn, user) do
115
    conn
116
    |> GuardianImpl.Plug.sign_in(user)
117
    |> GuardianImpl.Plug.current_token()
118
    |> case do
2✔
119
      nil ->
120
        conn
121
        |> put_status(:bad_request)
122
        |> put_view(ErrorView)
123
        |> render("error.json", message: @err_authentication_failed)
×
124

125
      token ->
126
        conn
127
        |> put_view(UserView)
128
        |> render("user_with_token.json", %{user: user, token: token})
2✔
129
    end
130
  end
131

132
  # Add supported providers here. If provider is not supported, it will raise
133
  defp provider_atom!("facebook"), do: :facebook
×
134
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

© 2026 Coveralls, Inc