Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop
[akkoma] / lib / pleroma / web / oauth / app.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.OAuth.App do
6 use Ecto.Schema
7 import Ecto.Changeset
8 alias Pleroma.Repo
9
10 @type t :: %__MODULE__{}
11
12 schema "apps" do
13 field(:client_name, :string)
14 field(:redirect_uris, :string)
15 field(:scopes, {:array, :string}, default: [])
16 field(:website, :string)
17 field(:client_id, :string)
18 field(:client_secret, :string)
19
20 timestamps()
21 end
22
23 def register_changeset(struct, params \\ %{}) do
24 changeset =
25 struct
26 |> cast(params, [:client_name, :redirect_uris, :scopes, :website])
27 |> validate_required([:client_name, :redirect_uris, :scopes])
28
29 if changeset.valid? do
30 changeset
31 |> put_change(
32 :client_id,
33 :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
34 )
35 |> put_change(
36 :client_secret,
37 :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
38 )
39 else
40 changeset
41 end
42 end
43
44 @doc """
45 Gets app by attrs or create new with attrs.
46 And updates the scopes if need.
47 """
48 @spec get_or_make(map(), list(String.t())) :: {:ok, App.t()} | {:error, Ecto.Changeset.t()}
49 def get_or_make(attrs, scopes) do
50 with %__MODULE__{} = app <- Repo.get_by(__MODULE__, attrs) do
51 update_scopes(app, scopes)
52 else
53 _e ->
54 %__MODULE__{}
55 |> register_changeset(Map.put(attrs, :scopes, scopes))
56 |> Repo.insert()
57 end
58 end
59
60 defp update_scopes(%__MODULE__{} = app, []), do: {:ok, app}
61 defp update_scopes(%__MODULE__{scopes: scopes} = app, scopes), do: {:ok, app}
62
63 defp update_scopes(%__MODULE__{} = app, scopes) do
64 app
65 |> change(%{scopes: scopes})
66 |> Repo.update()
67 end
68 end