AdminAPI: Confirm user account, resend confirmation email
This commit is contained in:
parent
09b4f7269e
commit
46eb160135
|
@ -67,6 +67,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Mastodon API: Add the `recipients` parameter to `GET /api/v1/conversations`
|
- Mastodon API: Add the `recipients` parameter to `GET /api/v1/conversations`
|
||||||
- Configuration: `feed` option for user atom feed.
|
- Configuration: `feed` option for user atom feed.
|
||||||
- Pleroma API: Add Emoji reactions
|
- Pleroma API: Add Emoji reactions
|
||||||
|
- Admin API: `PATCH /api/pleroma/users/confirm_email` to confirm email for multiple users, `PATCH /api/pleroma/users/resend_confirmation_email` to resend confirmation email for multiple users
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -878,3 +878,19 @@ Compile time settings (need instance reboot):
|
||||||
- Authentication: required
|
- Authentication: required
|
||||||
- Params: None
|
- Params: None
|
||||||
- Response: JSON, "ok" and 200 status
|
- Response: JSON, "ok" and 200 status
|
||||||
|
|
||||||
|
## `PATCH /api/pleroma/admin/users/confirm_email`
|
||||||
|
|
||||||
|
### Confirm users' emails
|
||||||
|
|
||||||
|
- Params:
|
||||||
|
- `nicknames`
|
||||||
|
- Response: Array of user nicknames
|
||||||
|
|
||||||
|
## `PATCH /api/pleroma/admin/users/resend_confirmation_email`
|
||||||
|
|
||||||
|
### Resend confirmation email
|
||||||
|
|
||||||
|
- Params:
|
||||||
|
- `nicknames`
|
||||||
|
- Response: Array of user nicknames
|
||||||
|
|
|
@ -624,7 +624,31 @@ def get_log_entry_message(%ModerationLog{
|
||||||
"subject" => subjects
|
"subject" => subjects
|
||||||
}
|
}
|
||||||
}) do
|
}) do
|
||||||
"@#{actor_nickname} force password reset for users: #{users_to_nicknames_string(subjects)}"
|
"@#{actor_nickname} forced password reset for users: #{users_to_nicknames_string(subjects)}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "confirm_email",
|
||||||
|
"subject" => subjects
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} confirmed email for users: #{users_to_nicknames_string(subjects)}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec get_log_entry_message(ModerationLog) :: String.t()
|
||||||
|
def get_log_entry_message(%ModerationLog{
|
||||||
|
data: %{
|
||||||
|
"actor" => %{"nickname" => actor_nickname},
|
||||||
|
"action" => "resend_confirmation_email",
|
||||||
|
"subject" => subjects
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
"@#{actor_nickname} re-sent confirmation email for users: #{
|
||||||
|
users_to_nicknames_string(subjects)
|
||||||
|
}"
|
||||||
end
|
end
|
||||||
|
|
||||||
defp nicknames_to_string(nicknames) do
|
defp nicknames_to_string(nicknames) do
|
||||||
|
|
|
@ -489,6 +489,10 @@ def try_send_confirmation_email(%User{} = user) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def try_send_confirmation_email(users) do
|
||||||
|
Enum.map(users, &try_send_confirmation_email/1)
|
||||||
|
end
|
||||||
|
|
||||||
def needs_update?(%User{local: true}), do: false
|
def needs_update?(%User{local: true}), do: false
|
||||||
|
|
||||||
def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true
|
def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true
|
||||||
|
@ -1572,6 +1576,11 @@ def toggle_confirmation(%User{} = user) do
|
||||||
|> update_and_set_cache()
|
|> update_and_set_cache()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec toggle_confirmation([User.t()]) :: [{:ok, User.t()} | {:error, Changeset.t()}]
|
||||||
|
def toggle_confirmation(users) do
|
||||||
|
Enum.map(users, &toggle_confirmation/1)
|
||||||
|
end
|
||||||
|
|
||||||
def get_mascot(%{mascot: %{} = mascot}) when not is_nil(mascot) do
|
def get_mascot(%{mascot: %{} = mascot}) when not is_nil(mascot) do
|
||||||
mascot
|
mascot
|
||||||
end
|
end
|
||||||
|
|
|
@ -335,7 +335,7 @@ def list_users(conn, params) do
|
||||||
}
|
}
|
||||||
|
|
||||||
with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
|
with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
|
||||||
{:ok, users, count} <- filter_relay_user(users, count),
|
{:ok, users, count} <- filter_service_users(users, count),
|
||||||
do:
|
do:
|
||||||
conn
|
conn
|
||||||
|> json(
|
|> json(
|
||||||
|
@ -347,15 +347,16 @@ def list_users(conn, params) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp filter_relay_user(users, count) do
|
defp filter_service_users(users, count) do
|
||||||
filtered_users = Enum.reject(users, &relay_user?/1)
|
filtered_users = Enum.reject(users, &service_user?/1)
|
||||||
count = if Enum.any?(users, &relay_user?/1), do: length(filtered_users), else: count
|
count = if Enum.any?(users, &service_user?/1), do: length(filtered_users), else: count
|
||||||
|
|
||||||
{:ok, filtered_users, count}
|
{:ok, filtered_users, count}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp relay_user?(user) do
|
defp service_user?(user) do
|
||||||
user.ap_id == Relay.relay_ap_id()
|
String.match?(user.ap_id, ~r/.*\/relay$/) or
|
||||||
|
String.match?(user.ap_id, ~r/.*\/internal\/fetch$/)
|
||||||
end
|
end
|
||||||
|
|
||||||
@filters ~w(local external active deactivated is_admin is_moderator)
|
@filters ~w(local external active deactivated is_admin is_moderator)
|
||||||
|
@ -799,6 +800,34 @@ def reload_emoji(conn, _params) do
|
||||||
conn |> json("ok")
|
conn |> json("ok")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
|
users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
|
||||||
|
|
||||||
|
User.toggle_confirmation(users)
|
||||||
|
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
subject: users,
|
||||||
|
action: "confirm_email"
|
||||||
|
})
|
||||||
|
|
||||||
|
conn |> json("")
|
||||||
|
end
|
||||||
|
|
||||||
|
def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
|
users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
|
||||||
|
|
||||||
|
User.try_send_confirmation_email(users)
|
||||||
|
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
actor: admin,
|
||||||
|
subject: users,
|
||||||
|
action: "resend_confirmation_email"
|
||||||
|
})
|
||||||
|
|
||||||
|
conn |> json("")
|
||||||
|
end
|
||||||
|
|
||||||
def errors(conn, {:error, :not_found}) do
|
def errors(conn, {:error, :not_found}) do
|
||||||
conn
|
conn
|
||||||
|> put_status(:not_found)
|
|> put_status(:not_found)
|
||||||
|
|
|
@ -36,7 +36,8 @@ def render("show.json", %{user: user}) do
|
||||||
"deactivated" => user.deactivated,
|
"deactivated" => user.deactivated,
|
||||||
"local" => user.local,
|
"local" => user.local,
|
||||||
"roles" => User.roles(user),
|
"roles" => User.roles(user),
|
||||||
"tags" => user.tags || []
|
"tags" => user.tags || [],
|
||||||
|
"confirmation_pending" => user.confirmation_pending
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,9 @@ defmodule Pleroma.Web.Router do
|
||||||
get("/users/:nickname", AdminAPIController, :user_show)
|
get("/users/:nickname", AdminAPIController, :user_show)
|
||||||
get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses)
|
get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses)
|
||||||
|
|
||||||
|
patch("/users/confirm_email", AdminAPIController, :confirm_email)
|
||||||
|
patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email)
|
||||||
|
|
||||||
get("/reports", AdminAPIController, :list_reports)
|
get("/reports", AdminAPIController, :list_reports)
|
||||||
get("/grouped_reports", AdminAPIController, :list_grouped_reports)
|
get("/grouped_reports", AdminAPIController, :list_grouped_reports)
|
||||||
get("/reports/:id", AdminAPIController, :report_show)
|
get("/reports/:id", AdminAPIController, :report_show)
|
||||||
|
|
|
@ -2839,6 +2839,68 @@ test "DELETE /relay", %{admin: admin} do
|
||||||
"@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
|
"@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "PATCH /confirm_email" do
|
||||||
|
setup %{conn: conn} do
|
||||||
|
admin = insert(:user, is_admin: true)
|
||||||
|
|
||||||
|
%{conn: assign(conn, :user, admin), admin: admin}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it confirms emails of two users", %{admin: admin} do
|
||||||
|
[first_user, second_user] = insert_pair(:user, confirmation_pending: true)
|
||||||
|
|
||||||
|
assert first_user.confirmation_pending == true
|
||||||
|
assert second_user.confirmation_pending == true
|
||||||
|
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, admin)
|
||||||
|
|> patch("/api/pleroma/admin/users/confirm_email", %{
|
||||||
|
nicknames: [
|
||||||
|
first_user.nickname,
|
||||||
|
second_user.nickname
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert first_user.confirmation_pending == true
|
||||||
|
assert second_user.confirmation_pending == true
|
||||||
|
|
||||||
|
log_entry = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||||
|
"@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{
|
||||||
|
second_user.nickname
|
||||||
|
}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH /resend_confirmation_email" do
|
||||||
|
setup %{conn: conn} do
|
||||||
|
admin = insert(:user, is_admin: true)
|
||||||
|
|
||||||
|
%{conn: assign(conn, :user, admin), admin: admin}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it resend emails for two users", %{admin: admin} do
|
||||||
|
[first_user, second_user] = insert_pair(:user, confirmation_pending: true)
|
||||||
|
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, admin)
|
||||||
|
|> patch("/api/pleroma/admin/users/resend_confirmation_email", %{
|
||||||
|
nicknames: [
|
||||||
|
first_user.nickname,
|
||||||
|
second_user.nickname
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
log_entry = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||||
|
"@#{admin.nickname} re-sent confirmation email for users: @#{first_user.nickname}, @#{
|
||||||
|
second_user.nickname
|
||||||
|
}"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Needed for testing
|
# Needed for testing
|
||||||
|
|
Loading…
Reference in a new issue