Fix toggle_deactivated to reactivate a deactivated user
[akkoma] / lib / mix / tasks / pleroma / user.ex
1 defmodule Mix.Tasks.Pleroma.User do
2 use Mix.Task
3 alias Pleroma.{Repo, User}
4
5 @shortdoc "Manages Pleroma users"
6 @moduledoc """
7 Manages Pleroma users.
8
9 ## Create a new user.
10
11 mix pleroma.user new NICKNAME EMAIL [OPTION...]
12
13 Options:
14 - `--name NAME` - the user's name (i.e., "Lain Iwakura")
15 - `--bio BIO` - the user's bio
16 - `--password PASSWORD` - the user's password
17 - `--moderator`/`--no-moderator` - whether the user is a moderator
18
19 ## Delete the user's account.
20
21 mix pleroma.user rm NICKNAME
22
23 ## Deactivate or activate the user's account.
24
25 mix pleroma.user toggle_activated NICKNAME
26
27 ## Create a password reset link.
28
29 mix pleroma.user reset_password NICKNAME
30
31 ## Set the value of the given user's settings.
32
33 mix pleroma.user set NICKNAME [OPTION...]
34
35 Options:
36 - `--locked`/`--no-locked` - whether the user's account is locked
37 - `--moderator`/`--no-moderator` - whether the user is a moderator
38 """
39
40 def run(["new", nickname, email | rest]) do
41 {options, [], []} =
42 OptionParser.parse(
43 rest,
44 strict: [
45 name: :string,
46 bio: :string,
47 password: :string,
48 moderator: :boolean
49 ]
50 )
51
52 name = Keyword.get(options, :name, nickname)
53 bio = Keyword.get(options, :bio, "")
54
55 {password, generated_password?} =
56 case Keyword.get(options, :password) do
57 nil ->
58 {:crypto.strong_rand_bytes(16) |> Base.encode64(), true}
59
60 password ->
61 {password, false}
62 end
63
64 moderator? = Keyword.get(options, :moderator, false)
65
66 Mix.shell().info("""
67 A user will be created with the following information:
68 - nickname: #{nickname}
69 - email: #{email}
70 - password: #{
71 if(generated_password?, do: "[generated; a reset link will be created]", else: password)
72 }
73 - name: #{name}
74 - bio: #{bio}
75 - moderator: #{if(moderator?, do: "true", else: "false")}
76 """)
77
78 proceed? = Mix.shell().yes?("Continue?")
79
80 unless not proceed? do
81 Mix.Task.run("app.start")
82
83 params =
84 %{
85 nickname: nickname,
86 email: email,
87 password: password,
88 password_confirmation: password,
89 name: name,
90 bio: bio
91 }
92 |> IO.inspect()
93
94 user = User.register_changeset(%User{}, params)
95 Repo.insert!(user)
96
97 Mix.shell().info("User #{nickname} created")
98
99 if moderator? do
100 run(["set", nickname, "--moderator"])
101 end
102
103 if generated_password? do
104 run(["reset_password", nickname])
105 end
106 else
107 Mix.shell().info("User will not be created.")
108 end
109 end
110
111 def run(["rm", nickname]) do
112 Mix.Task.run("app.start")
113
114 with %User{local: true} = user <- User.get_by_nickname(nickname) do
115 User.delete(user)
116 end
117
118 Mix.shell().info("User #{nickname} deleted.")
119 end
120
121 def run(["toggle_activated", nickname]) do
122 Mix.Task.run("app.start")
123
124 with user <- User.get_by_nickname(nickname) do
125 User.deactivate(user, !user.info["deactivated"])
126 end
127 end
128
129 def run(["reset_password", nickname]) do
130 Mix.Task.run("app.start")
131
132 with %User{local: true} = user <- User.get_by_nickname(nickname),
133 {:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do
134 Mix.shell().info("Generated password reset token for #{user.nickname}")
135
136 IO.puts(
137 "URL: #{
138 Pleroma.Web.Router.Helpers.util_url(
139 Pleroma.Web.Endpoint,
140 :show_password_reset,
141 token.token
142 )
143 }"
144 )
145 else
146 _ ->
147 Mix.shell().error("No local user #{nickname}")
148 end
149 end
150
151 def run(["set", nickname | rest]) do
152 {options, [], []} =
153 OptionParser.parse(
154 rest,
155 strict: [
156 moderator: :boolean,
157 locked: :boolean
158 ]
159 )
160
161 case Keyword.get(options, :moderator) do
162 nil -> nil
163 value -> set_moderator(nickname, value)
164 end
165
166 case Keyword.get(options, :locked) do
167 nil -> nil
168 value -> set_locked(nickname, value)
169 end
170 end
171
172 defp set_moderator(nickname, value) do
173 Application.ensure_all_started(:pleroma)
174
175 with %User{local: true} = user <- User.get_by_nickname(nickname) do
176 info =
177 user.info
178 |> Map.put("is_moderator", value)
179
180 cng = User.info_changeset(user, %{info: info})
181 {:ok, user} = User.update_and_set_cache(cng)
182
183 Mix.shell().info("Moderator status of #{nickname}: #{user.info["is_moderator"]}")
184 else
185 _ ->
186 Mix.shell().error("No local user #{nickname}")
187 end
188 end
189
190 defp set_locked(nickname, value) do
191 Mix.Ecto.ensure_started(Repo, [])
192
193 with %User{local: true} = user <- User.get_by_nickname(nickname) do
194 info =
195 user.info
196 |> Map.put("locked", value)
197
198 cng = User.info_changeset(user, %{info: info})
199 user = Repo.update!(cng)
200
201 IO.puts("Locked status of #{nickname}: #{user.info["locked"]}")
202 else
203 _ ->
204 IO.puts("No local user #{nickname}")
205 end
206 end
207 end