Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.2KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
  5. import Pleroma.Web.Gettext
  6. alias Pleroma.Emails.Mailer
  7. alias Pleroma.Emails.UserEmail
  8. alias Pleroma.Repo
  9. alias Pleroma.User
  10. alias Pleroma.UserInviteToken
  11. def register_user(params, opts \\ []) do
  12. params =
  13. params
  14. |> Map.take([:email, :token, :password])
  15. |> Map.put(:bio, params |> Map.get(:bio, "") |> User.parse_bio())
  16. |> Map.put(:nickname, params[:username])
  17. |> Map.put(:name, Map.get(params, :fullname, params[:username]))
  18. |> Map.put(:password_confirmation, params[:password])
  19. |> Map.put(:registration_reason, params[:reason])
  20. if Pleroma.Config.get([:instance, :registrations_open]) do
  21. create_user(params, opts)
  22. else
  23. create_user_with_invite(params, opts)
  24. end
  25. end
  26. defp create_user_with_invite(params, opts) do
  27. with %{token: token} when is_binary(token) <- params,
  28. %UserInviteToken{} = invite <- Repo.get_by(UserInviteToken, %{token: token}),
  29. true <- UserInviteToken.valid_invite?(invite) do
  30. UserInviteToken.update_usage!(invite)
  31. create_user(params, opts)
  32. else
  33. nil -> {:error, "Invalid token"}
  34. _ -> {:error, "Expired token"}
  35. end
  36. end
  37. defp create_user(params, opts) do
  38. changeset = User.register_changeset(%User{}, params, opts)
  39. case User.register(changeset) do
  40. {:ok, user} ->
  41. maybe_notify_admins(user)
  42. {:ok, user}
  43. {:error, changeset} ->
  44. errors =
  45. changeset
  46. |> Ecto.Changeset.traverse_errors(fn {msg, _opts} -> msg end)
  47. |> Jason.encode!()
  48. {:error, errors}
  49. end
  50. end
  51. defp maybe_notify_admins(%User{} = account) do
  52. if Pleroma.Config.get([:instance, :account_approval_required]) do
  53. User.all_superusers()
  54. |> Enum.filter(fn user -> not is_nil(user.email) end)
  55. |> Enum.each(fn superuser ->
  56. superuser
  57. |> Pleroma.Emails.AdminEmail.new_unapproved_registration(account)
  58. |> Pleroma.Emails.Mailer.deliver_async()
  59. end)
  60. end
  61. end
  62. def password_reset(nickname_or_email) do
  63. with true <- is_binary(nickname_or_email),
  64. %User{local: true, email: email, deactivated: false} = user when is_binary(email) <-
  65. User.get_by_nickname_or_email(nickname_or_email),
  66. {:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
  67. user
  68. |> UserEmail.password_reset_email(token_record.token)
  69. |> Mailer.deliver_async()
  70. {:ok, :enqueued}
  71. else
  72. _ ->
  73. {:ok, :noop}
  74. end
  75. end
  76. def validate_captcha(app, params) do
  77. if app.trusted || not Pleroma.Captcha.enabled?() do
  78. :ok
  79. else
  80. do_validate_captcha(params)
  81. end
  82. end
  83. defp do_validate_captcha(params) do
  84. with :ok <- validate_captcha_presence(params),
  85. :ok <-
  86. Pleroma.Captcha.validate(
  87. params[:captcha_token],
  88. params[:captcha_solution],
  89. params[:captcha_answer_data]
  90. ) do
  91. :ok
  92. else
  93. {:error, :captcha_error} ->
  94. captcha_error(dgettext("errors", "CAPTCHA Error"))
  95. {:error, :invalid} ->
  96. captcha_error(dgettext("errors", "Invalid CAPTCHA"))
  97. {:error, :kocaptcha_service_unavailable} ->
  98. captcha_error(dgettext("errors", "Kocaptcha service unavailable"))
  99. {:error, :expired} ->
  100. captcha_error(dgettext("errors", "CAPTCHA expired"))
  101. {:error, :already_used} ->
  102. captcha_error(dgettext("errors", "CAPTCHA already used"))
  103. {:error, :invalid_answer_data} ->
  104. captcha_error(dgettext("errors", "Invalid answer data"))
  105. {:error, error} ->
  106. captcha_error(error)
  107. end
  108. end
  109. defp validate_captcha_presence(params) do
  110. [:captcha_solution, :captcha_token, :captcha_answer_data]
  111. |> Enum.find_value(:ok, fn key ->
  112. unless is_binary(params[key]) do
  113. error = dgettext("errors", "Invalid CAPTCHA (Missing parameter: %{name})", name: key)
  114. {:error, error}
  115. end
  116. end)
  117. end
  118. # For some reason FE expects error message to be a serialized JSON
  119. defp captcha_error(error), do: {:error, Jason.encode!(%{captcha: [error]})}
  120. end