authorization.ex 1.76 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.Authorization do
  use Ecto.Schema

Haelwenn's avatar
Haelwenn committed
8
  alias Pleroma.Repo
9
  alias Pleroma.User
Haelwenn's avatar
Haelwenn committed
10
  alias Pleroma.Web.OAuth.App
11
  alias Pleroma.Web.OAuth.Authorization
12

Haelwenn's avatar
Haelwenn committed
13 14
  import Ecto.Changeset
  import Ecto.Query
15

16
  schema "oauth_authorizations" do
lain's avatar
lain committed
17
    field(:token, :string)
18
    field(:scopes, {:array, :string}, default: [])
rinpatch's avatar
rinpatch committed
19
    field(:valid_until, :naive_datetime_usec)
lain's avatar
lain committed
20
    field(:used, :boolean, default: false)
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
  def create_authorization(%App{} = app, %User{} = user, scopes \\ nil) do
    scopes = scopes || app.scopes
29
    token = :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
30 31 32 33 34 35

    authorization = %Authorization{
      token: token,
      used: false,
      user_id: user.id,
      app_id: app.id,
36
      scopes: scopes,
lain's avatar
lain committed
37
      valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10)
38 39 40 41
    }

    Repo.insert(authorization)
  end
42 43 44 45 46 47 48 49

  def use_changeset(%Authorization{} = auth, params) do
    auth
    |> cast(params, [:used])
    |> validate_required([:used])
  end

  def use_token(%Authorization{used: false, valid_until: valid_until} = auth) do
lain's avatar
lain committed
50
    if NaiveDateTime.diff(NaiveDateTime.utc_now(), valid_until) < 0 do
51 52
      Repo.update(use_changeset(auth, %{used: true}))
    else
lain's avatar
lain committed
53
      {:error, "token expired"}
54 55
    end
  end
lain's avatar
lain committed
56

lain's avatar
lain committed
57
  def use_token(%Authorization{used: true}), do: {:error, "already used"}
58 59 60 61 62 63 64 65

  def delete_user_authorizations(%User{id: user_id}) do
    from(
      a in Pleroma.Web.OAuth.Authorization,
      where: a.user_id == ^user_id
    )
    |> Repo.delete_all()
  end
66
end