token.ex 1.87 KB
Newer Older
1
# Pleroma: A lightweight social networking server
kaniini's avatar
kaniini committed
2
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 4
# SPDX-License-Identifier: AGPL-3.0-only

5 6 7
defmodule Pleroma.Web.OAuth.Token do
  use Ecto.Schema

8 9
  import Ecto.Query

Haelwenn's avatar
Haelwenn committed
10
  alias Pleroma.Repo
11
  alias Pleroma.User
Haelwenn's avatar
Haelwenn committed
12 13
  alias Pleroma.Web.OAuth.App
  alias Pleroma.Web.OAuth.Authorization
14
  alias Pleroma.Web.OAuth.Token
15 16

  schema "oauth_tokens" do
lain's avatar
lain committed
17 18
    field(:token, :string)
    field(:refresh_token, :string)
19
    field(:scopes, {:array, :string}, default: [])
rinpatch's avatar
rinpatch committed
20
    field(:valid_until, :naive_datetime_usec)
href's avatar
href committed
21
    belongs_to(:user, Pleroma.User, type: Pleroma.FlakeId)
lain's avatar
lain committed
22
    belongs_to(:app, App)
23 24 25 26

    timestamps()
  end

27 28 29
  def exchange_token(app, auth) do
    with {:ok, auth} <- Authorization.use_token(auth),
         true <- auth.app_id == app.id do
30
      create_token(app, Repo.get(User, auth.user_id), auth.scopes)
31 32 33
    end
  end

34 35
  def create_token(%App{} = app, %User{} = user, scopes \\ nil) do
    scopes = scopes || app.scopes
36 37
    token = :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
    refresh_token = :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
38 39 40 41

    token = %Token{
      token: token,
      refresh_token: refresh_token,
42
      scopes: scopes,
43 44
      user_id: user.id,
      app_id: app.id,
lain's avatar
lain committed
45
      valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10)
46 47 48 49
    }

    Repo.insert(token)
  end
50 51 52

  def delete_user_tokens(%User{id: user_id}) do
    from(
Maxim Filippov's avatar
Maxim Filippov committed
53
      t in Token,
54 55 56 57
      where: t.user_id == ^user_id
    )
    |> Repo.delete_all()
  end
Maxim Filippov's avatar
Maxim Filippov committed
58

Maxim Filippov's avatar
Maxim Filippov committed
59
  def delete_user_token(%User{id: user_id}, token_id) do
Maxim Filippov's avatar
Maxim Filippov committed
60
    from(
Maxim Filippov's avatar
Maxim Filippov committed
61
      t in Token,
Maxim Filippov's avatar
Maxim Filippov committed
62 63 64 65 66 67 68 69 70
      where: t.user_id == ^user_id,
      where: t.id == ^token_id
    )
    |> Repo.delete_all()
  end

  def get_user_tokens(%User{id: user_id}) do
    from(
      t in Token,
Maxim Filippov's avatar
Maxim Filippov committed
71 72 73
      where: t.user_id == ^user_id
    )
    |> Repo.all()
74
    |> Repo.preload(:app)
Maxim Filippov's avatar
Maxim Filippov committed
75
  end
76
end