logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

app.ex (4239B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.OAuth.App do
  5. use Ecto.Schema
  6. import Ecto.Changeset
  7. import Ecto.Query
  8. alias Pleroma.Repo
  9. alias Pleroma.User
  10. @type t :: %__MODULE__{}
  11. schema "apps" do
  12. field(:client_name, :string)
  13. field(:redirect_uris, :string)
  14. field(:scopes, {:array, :string}, default: [])
  15. field(:website, :string)
  16. field(:client_id, :string)
  17. field(:client_secret, :string)
  18. field(:trusted, :boolean, default: false)
  19. belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
  20. has_many(:oauth_authorizations, Pleroma.Web.OAuth.Authorization, on_delete: :delete_all)
  21. has_many(:oauth_tokens, Pleroma.Web.OAuth.Token, on_delete: :delete_all)
  22. timestamps()
  23. end
  24. @spec changeset(t(), map()) :: Ecto.Changeset.t()
  25. def changeset(struct, params) do
  26. cast(struct, params, [:client_name, :redirect_uris, :scopes, :website, :trusted, :user_id])
  27. end
  28. @spec register_changeset(t(), map()) :: Ecto.Changeset.t()
  29. def register_changeset(struct, params \\ %{}) do
  30. changeset =
  31. struct
  32. |> changeset(params)
  33. |> validate_required([:client_name, :redirect_uris, :scopes])
  34. if changeset.valid? do
  35. changeset
  36. |> put_change(
  37. :client_id,
  38. :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
  39. )
  40. |> put_change(
  41. :client_secret,
  42. :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
  43. )
  44. else
  45. changeset
  46. end
  47. end
  48. @spec create(map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
  49. def create(params) do
  50. %__MODULE__{}
  51. |> register_changeset(params)
  52. |> Repo.insert()
  53. end
  54. @spec update(pos_integer(), map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
  55. def update(id, params) do
  56. with %__MODULE__{} = app <- Repo.get(__MODULE__, id) do
  57. app
  58. |> changeset(params)
  59. |> Repo.update()
  60. end
  61. end
  62. @doc """
  63. Gets app by attrs or create new with attrs.
  64. And updates the scopes if need.
  65. """
  66. @spec get_or_make(map(), list(String.t())) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
  67. def get_or_make(attrs, scopes) do
  68. with %__MODULE__{} = app <- Repo.get_by(__MODULE__, attrs) do
  69. update_scopes(app, scopes)
  70. else
  71. _e ->
  72. %__MODULE__{}
  73. |> register_changeset(Map.put(attrs, :scopes, scopes))
  74. |> Repo.insert()
  75. end
  76. end
  77. defp update_scopes(%__MODULE__{} = app, []), do: {:ok, app}
  78. defp update_scopes(%__MODULE__{scopes: scopes} = app, scopes), do: {:ok, app}
  79. defp update_scopes(%__MODULE__{} = app, scopes) do
  80. app
  81. |> change(%{scopes: scopes})
  82. |> Repo.update()
  83. end
  84. @spec search(map()) :: {:ok, [t()], non_neg_integer()}
  85. def search(params) do
  86. query = from(a in __MODULE__)
  87. query =
  88. if params[:client_name] do
  89. from(a in query, where: a.client_name == ^params[:client_name])
  90. else
  91. query
  92. end
  93. query =
  94. if params[:client_id] do
  95. from(a in query, where: a.client_id == ^params[:client_id])
  96. else
  97. query
  98. end
  99. query =
  100. if Map.has_key?(params, :trusted) do
  101. from(a in query, where: a.trusted == ^params[:trusted])
  102. else
  103. query
  104. end
  105. query =
  106. from(u in query,
  107. limit: ^params[:page_size],
  108. offset: ^((params[:page] - 1) * params[:page_size])
  109. )
  110. count = Repo.aggregate(__MODULE__, :count, :id)
  111. {:ok, Repo.all(query), count}
  112. end
  113. @spec get_user_apps(User.t()) :: {:ok, [t()], non_neg_integer()}
  114. def get_user_apps(%User{id: user_id}) do
  115. from(a in __MODULE__, where: a.user_id == ^user_id)
  116. |> Repo.all()
  117. end
  118. @spec destroy(pos_integer()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
  119. def destroy(id) do
  120. with %__MODULE__{} = app <- Repo.get(__MODULE__, id) do
  121. Repo.delete(app)
  122. end
  123. end
  124. @spec errors(Ecto.Changeset.t()) :: map()
  125. def errors(changeset) do
  126. Enum.reduce(changeset.errors, %{}, fn
  127. {:client_name, {error, _}}, acc ->
  128. Map.put(acc, :name, error)
  129. {key, {error, _}}, acc ->
  130. Map.put(acc, key, error)
  131. end)
  132. end
  133. end