logo

pleroma

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

user_invite_token.ex (3725B)


  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.UserInviteToken do
  5. use Ecto.Schema
  6. import Ecto.Changeset
  7. import Ecto.Query
  8. alias Pleroma.Repo
  9. alias Pleroma.UserInviteToken
  10. @type t :: %__MODULE__{}
  11. @type token :: String.t()
  12. schema "user_invite_tokens" do
  13. field(:token, :string)
  14. field(:used, :boolean, default: false)
  15. field(:max_use, :integer)
  16. field(:expires_at, :date)
  17. field(:uses, :integer, default: 0)
  18. field(:invite_type, :string)
  19. timestamps()
  20. end
  21. @spec create_invite(map()) :: {:ok, UserInviteToken.t()}
  22. def create_invite(params \\ %{}) do
  23. %UserInviteToken{}
  24. |> cast(params, [:max_use, :expires_at])
  25. |> add_token()
  26. |> assign_type()
  27. |> Repo.insert()
  28. end
  29. defp add_token(changeset) do
  30. token = :crypto.strong_rand_bytes(32) |> Base.url_encode64()
  31. put_change(changeset, :token, token)
  32. end
  33. defp assign_type(%{changes: %{max_use: _max_use, expires_at: _expires_at}} = changeset) do
  34. put_change(changeset, :invite_type, "reusable_date_limited")
  35. end
  36. defp assign_type(%{changes: %{expires_at: _expires_at}} = changeset) do
  37. put_change(changeset, :invite_type, "date_limited")
  38. end
  39. defp assign_type(%{changes: %{max_use: _max_use}} = changeset) do
  40. put_change(changeset, :invite_type, "reusable")
  41. end
  42. defp assign_type(changeset), do: put_change(changeset, :invite_type, "one_time")
  43. @spec list_invites() :: [UserInviteToken.t()]
  44. def list_invites do
  45. query = from(u in UserInviteToken, order_by: u.id)
  46. Repo.all(query)
  47. end
  48. @spec update_invite!(UserInviteToken.t(), map()) :: UserInviteToken.t() | no_return()
  49. def update_invite!(invite, changes) do
  50. change(invite, changes) |> Repo.update!()
  51. end
  52. @spec update_invite(UserInviteToken.t(), map()) ::
  53. {:ok, UserInviteToken.t()} | {:error, Ecto.Changeset.t()}
  54. def update_invite(invite, changes) do
  55. change(invite, changes) |> Repo.update()
  56. end
  57. @spec find_by_token!(token()) :: UserInviteToken.t() | no_return()
  58. def find_by_token!(token), do: Repo.get_by!(UserInviteToken, token: token)
  59. @spec find_by_token(token()) :: {:ok, UserInviteToken.t()} | nil
  60. def find_by_token(token) do
  61. with %UserInviteToken{} = invite <- Repo.get_by(UserInviteToken, token: token) do
  62. {:ok, invite}
  63. end
  64. end
  65. @spec valid_invite?(UserInviteToken.t()) :: boolean()
  66. def valid_invite?(%{invite_type: "one_time"} = invite) do
  67. not invite.used
  68. end
  69. def valid_invite?(%{invite_type: "date_limited"} = invite) do
  70. not_overdue_date?(invite) and not invite.used
  71. end
  72. def valid_invite?(%{invite_type: "reusable"} = invite) do
  73. invite.uses < invite.max_use and not invite.used
  74. end
  75. def valid_invite?(%{invite_type: "reusable_date_limited"} = invite) do
  76. not_overdue_date?(invite) and invite.uses < invite.max_use and not invite.used
  77. end
  78. defp not_overdue_date?(%{expires_at: expires_at}) do
  79. Date.compare(Date.utc_today(), expires_at) in [:lt, :eq]
  80. end
  81. @spec update_usage!(UserInviteToken.t()) :: nil | UserInviteToken.t() | no_return()
  82. def update_usage!(%{invite_type: "date_limited"}), do: nil
  83. def update_usage!(%{invite_type: "one_time"} = invite),
  84. do: update_invite!(invite, %{used: true})
  85. def update_usage!(%{invite_type: invite_type} = invite)
  86. when invite_type == "reusable" or invite_type == "reusable_date_limited" do
  87. changes = %{
  88. uses: invite.uses + 1
  89. }
  90. changes =
  91. if changes.uses >= invite.max_use do
  92. Map.put(changes, :used, true)
  93. else
  94. changes
  95. end
  96. update_invite!(invite, changes)
  97. end
  98. end