oauth_plug.ex 1.71 KB
Newer Older
1
2
defmodule Pleroma.Plugs.OAuthPlug do
  import Plug.Conn
Maksim's avatar
fix/273    
Maksim committed
3
  import Ecto.Query
4

Maksim's avatar
fix/273    
Maksim committed
5
6
7
8
9
10
11
12
13
  alias Pleroma.{
    User,
    Repo,
    Web.OAuth.Token
  }

  @realm_reg Regex.compile!("Bearer\:?\s+(.*)$", "i")

  def init(options), do: options
14
15

  def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
lain's avatar
lain committed
16

Thog's avatar
Thog committed
17
  def call(conn, _) do
Maksim's avatar
fix/273    
Maksim committed
18
19
    with {:ok, token} <- fetch_token(conn),
         {:ok, user} <- fetch_user(token) do
20
      conn
Martin's avatar
Martin committed
21
      |> assign(:token, token)
22
23
24
25
26
      |> assign(:user, user)
    else
      _ -> conn
    end
  end
Maksim's avatar
fix/273    
Maksim committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

  # Gets user by token
  #
  @spec fetch_user(String.t()) :: {:ok, User.t()} | nil
  defp fetch_user(token) do
    query = from(q in Token, where: q.token == ^token, preload: [:user])

    with %Token{user: %{info: %{deactivated: false} = _} = user} <- Repo.one(query) do
      {:ok, user}
    end
  end

  # Gets token from session by :oauth_token key
  #
  @spec fetch_token_from_session(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()}
  defp fetch_token_from_session(conn) do
    case get_session(conn, :oauth_token) do
      nil -> :no_token_found
      token -> {:ok, token}
    end
  end

  # Gets token from headers
  #
  @spec fetch_token(Plug.Conn.t()) :: :no_token_found | {:ok, String.t()}
  defp fetch_token(%Plug.Conn{} = conn) do
    headers = get_req_header(conn, "authorization")

    with :no_token_found <- fetch_token(headers),
         do: fetch_token_from_session(conn)
  end

  @spec fetch_token(Keyword.t()) :: :no_token_found | {:ok, String.t()}
  defp fetch_token([]), do: :no_token_found

  defp fetch_token([token | tail]) do
    trimmed_token = String.trim(token)

    case Regex.run(@realm_reg, trimmed_token) do
      [_, match] -> {:ok, String.trim(match)}
      _ -> fetch_token(tail)
    end
  end
70
end