Admin API: Ability to list all followed relays See merge request pleroma/pleroma!1835merge-requests/1875/head
@@ -49,6 +49,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
- Mastodon API: Add `exclude_visibilities` parameter to the timeline and notification endpoints | |||
- Admin API: `/users/:nickname/toggle_activation` endpoint is now deprecated in favor of: `/users/activate`, `/users/deactivate`, both accept `nicknames` array | |||
- Admin API: `POST/DELETE /api/pleroma/admin/users/:nickname/permission_group/:permission_group` are deprecated in favor of: `POST/DELETE /api/pleroma/admin/users/permission_group/:permission_group` (both accept `nicknames` array), `DELETE /api/pleroma/admin/users` (`nickname` query param or `nickname` sent in JSON body) is deprecated in favor of: `DELETE /api/pleroma/admin/users` (`nicknames` query array param or `nicknames` sent in JSON body). | |||
- Admin API: Add `GET /api/pleroma/admin/relay` endpoint - lists all followed relays | |||
### Changed | |||
- **Breaking:** Elixir >=1.8 is now required (was >= 1.7) | |||
- **Breaking:** Admin API: Return link alongside with token on password reset | |||
- Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings) | |||
- Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler | |||
- Admin API: Return `total` when querying for reports | |||
- Mastodon API: Return `pleroma.direct_conversation_id` when creating a direct message (`POST /api/v1/statuses`) | |||
- Admin API: Return link alongside with token on password reset | |||
- MRF (Simple Policy): Also use `:accept`/`:reject` on the actors rather than only their activities | |||
- OStatus: Extract RSS functionality | |||
- Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`) | |||
- Mastodon API: Mark the direct conversation as read for the author when they send a new direct message | |||
</details> | |||
### Fixed | |||
@@ -289,6 +289,14 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret | |||
- Response: | |||
- On success: URL of the unfollowed relay | |||
## `GET /api/pleroma/admin/relay` | |||
### List Relays | |||
- Params: none | |||
- Response: | |||
- On success: JSON array of relays | |||
## `/api/pleroma/admin/users/invite_token` | |||
### Create an account registration invite token | |||
@@ -5,7 +5,6 @@ | |||
defmodule Mix.Tasks.Pleroma.Relay do | |||
use Mix.Task | |||
import Mix.Pleroma | |||
alias Pleroma.User | |||
alias Pleroma.Web.ActivityPub.Relay | |||
@shortdoc "Manages remote relays" | |||
@@ -36,13 +35,10 @@ defmodule Mix.Tasks.Pleroma.Relay do | |||
def run(["list"]) do | |||
start_pleroma() | |||
with %User{following: following} = _user <- Relay.get_actor() do | |||
following | |||
|> Enum.map(fn entry -> URI.parse(entry).host end) | |||
|> Enum.uniq() | |||
|> Enum.each(&shell_info(&1)) | |||
with {:ok, list} <- Relay.list() do | |||
list |> Enum.each(&shell_info(&1)) | |||
else | |||
e -> shell_error("Error while fetching relay subscription list: #{inspect(e)}") | |||
{:error, e} -> shell_error("Error while fetching relay subscription list: #{inspect(e)}") | |||
end | |||
end | |||
end |
@@ -51,6 +51,20 @@ defmodule Pleroma.Web.ActivityPub.Relay do | |||
def publish(_), do: {:error, "Not implemented"} | |||
@spec list() :: {:ok, [String.t()]} | {:error, any()} | |||
def list do | |||
with %User{following: following} = _user <- get_actor() do | |||
list = | |||
following | |||
|> Enum.map(fn entry -> URI.parse(entry).host end) | |||
|> Enum.uniq() | |||
{:ok, list} | |||
else | |||
error -> format_error(error) | |||
end | |||
end | |||
defp format_error({:error, error}), do: format_error(error) | |||
defp format_error(error) do | |||
@@ -481,6 +481,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||
render_error(conn, :forbidden, "You can't revoke your own admin status.") | |||
end | |||
def relay_list(conn, _params) do | |||
with {:ok, list} <- Relay.list() do | |||
json(conn, %{relays: list}) | |||
else | |||
_ -> | |||
conn | |||
|> put_status(500) | |||
end | |||
end | |||
def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do | |||
with {:ok, _message} <- Relay.follow(target) do | |||
ModerationLog.insert_log(%{ | |||
@@ -161,6 +161,7 @@ defmodule Pleroma.Web.Router do | |||
:right_delete_multiple | |||
) | |||
get("/relay", AdminAPIController, :relay_list) | |||
post("/relay", AdminAPIController, :relay_follow) | |||
delete("/relay", AdminAPIController, :relay_unfollow) | |||
@@ -17,6 +17,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
alias Pleroma.Web.MediaProxy | |||
import Pleroma.Factory | |||
setup_all do | |||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) | |||
:ok | |||
end | |||
describe "DELETE /api/pleroma/admin/users" do | |||
test "single user" do | |||
admin = insert(:user, info: %{is_admin: true}) | |||
@@ -2541,6 +2547,74 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do | |||
assert User.get_by_id(user.id).info.password_reset_pending == true | |||
end | |||
end | |||
describe "relays" do | |||
setup %{conn: conn} do | |||
admin = insert(:user, info: %{is_admin: true}) | |||
%{conn: assign(conn, :user, admin), admin: admin} | |||
end | |||
test "POST /relay", %{admin: admin} do | |||
conn = | |||
build_conn() | |||
|> assign(:user, admin) | |||
|> post("/api/pleroma/admin/relay", %{ | |||
relay_url: "http://mastodon.example.org/users/admin" | |||
}) | |||
assert json_response(conn, 200) == "http://mastodon.example.org/users/admin" | |||
log_entry = Repo.one(ModerationLog) | |||
assert ModerationLog.get_log_entry_message(log_entry) == | |||
"@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin" | |||
end | |||
test "GET /relay", %{admin: admin} do | |||
Pleroma.Web.ActivityPub.Relay.get_actor() | |||
|> Ecto.Changeset.change( | |||
following: [ | |||
"http://test-app.com/user/test1", | |||
"http://test-app.com/user/test1", | |||
"http://test-app-42.com/user/test1" | |||
] | |||
) | |||
|> Pleroma.User.update_and_set_cache() | |||
conn = | |||
build_conn() | |||
|> assign(:user, admin) | |||
|> get("/api/pleroma/admin/relay") | |||
assert json_response(conn, 200)["relays"] -- ["test-app.com", "test-app-42.com"] == [] | |||
end | |||
test "DELETE /relay", %{admin: admin} do | |||
build_conn() | |||
|> assign(:user, admin) | |||
|> post("/api/pleroma/admin/relay", %{ | |||
relay_url: "http://mastodon.example.org/users/admin" | |||
}) | |||
conn = | |||
build_conn() | |||
|> assign(:user, admin) | |||
|> delete("/api/pleroma/admin/relay", %{ | |||
relay_url: "http://mastodon.example.org/users/admin" | |||
}) | |||
assert json_response(conn, 200) == "http://mastodon.example.org/users/admin" | |||
[log_entry_one, log_entry_two] = Repo.all(ModerationLog) | |||
assert ModerationLog.get_log_entry_message(log_entry_one) == | |||
"@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin" | |||
assert ModerationLog.get_log_entry_message(log_entry_two) == | |||
"@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin" | |||
end | |||
end | |||
end | |||
# Needed for testing | |||