Merge branch 'mongoose-secure' into 'develop'
[akkoma] / lib / pleroma / web / twitter_api / twitter_api.ex
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
5 defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
6 alias Pleroma.Emails.Mailer
7 alias Pleroma.Emails.UserEmail
8 alias Pleroma.Repo
9 alias Pleroma.User
10 alias Pleroma.UserInviteToken
11
12 require Pleroma.Constants
13
14 def register_user(params, opts \\ []) do
15 token = params["token"]
16 trusted_app? = params["trusted_app"]
17
18 params = %{
19 nickname: params["nickname"],
20 name: params["fullname"],
21 bio: User.parse_bio(params["bio"]),
22 email: params["email"],
23 password: params["password"],
24 password_confirmation: params["confirm"],
25 captcha_solution: params["captcha_solution"],
26 captcha_token: params["captcha_token"],
27 captcha_answer_data: params["captcha_answer_data"]
28 }
29
30 captcha_enabled = Pleroma.Config.get([Pleroma.Captcha, :enabled])
31 # true if captcha is disabled or enabled and valid, false otherwise
32 captcha_ok =
33 if trusted_app? || not captcha_enabled do
34 :ok
35 else
36 Pleroma.Captcha.validate(
37 params[:captcha_token],
38 params[:captcha_solution],
39 params[:captcha_answer_data]
40 )
41 end
42
43 # Captcha invalid
44 if captcha_ok != :ok do
45 {:error, error} = captcha_ok
46 # I have no idea how this error handling works
47 {:error, %{error: Jason.encode!(%{captcha: [error]})}}
48 else
49 registration_process(
50 params,
51 %{
52 registrations_open: Pleroma.Config.get([:instance, :registrations_open]),
53 token: token
54 },
55 opts
56 )
57 end
58 end
59
60 defp registration_process(params, %{registrations_open: true}, opts) do
61 create_user(params, opts)
62 end
63
64 defp registration_process(params, %{token: token}, opts) do
65 invite =
66 unless is_nil(token) do
67 Repo.get_by(UserInviteToken, %{token: token})
68 end
69
70 valid_invite? = invite && UserInviteToken.valid_invite?(invite)
71
72 case invite do
73 nil ->
74 {:error, "Invalid token"}
75
76 invite when valid_invite? ->
77 UserInviteToken.update_usage!(invite)
78 create_user(params, opts)
79
80 _ ->
81 {:error, "Expired token"}
82 end
83 end
84
85 defp create_user(params, opts) do
86 changeset = User.register_changeset(%User{}, params, opts)
87
88 case User.register(changeset) do
89 {:ok, user} ->
90 {:ok, user}
91
92 {:error, changeset} ->
93 errors =
94 Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
95 |> Jason.encode!()
96
97 {:error, %{error: errors}}
98 end
99 end
100
101 def password_reset(nickname_or_email) do
102 with true <- is_binary(nickname_or_email),
103 %User{local: true, email: email} = user when not is_nil(email) <-
104 User.get_by_nickname_or_email(nickname_or_email),
105 {:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
106 user
107 |> UserEmail.password_reset_email(token_record.token)
108 |> Mailer.deliver_async()
109
110 {:ok, :enqueued}
111 else
112 false ->
113 {:error, "bad user identifier"}
114
115 %User{local: true, email: nil} ->
116 {:ok, :noop}
117
118 %User{local: false} ->
119 {:error, "remote user"}
120
121 nil ->
122 {:error, "unknown user"}
123 end
124 end
125 end