Commit c25a81b1 authored by kaniini's avatar kaniini

Merge branch 'feature/relay-list' into 'develop'

Admin API: Ability to list all followed relays

See merge request !1835
parents 4053a82f 019147f1
Pipeline #18827 passed with stages
in 57 minutes and 13 seconds
...@@ -49,6 +49,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ...@@ -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 - 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: `/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: `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> </details>
### Fixed ### Fixed
......
...@@ -289,6 +289,14 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret ...@@ -289,6 +289,14 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- Response: - Response:
- On success: URL of the unfollowed relay - 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` ## `/api/pleroma/admin/users/invite_token`
### Create an account registration invite token ### Create an account registration invite token
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
defmodule Mix.Tasks.Pleroma.Relay do defmodule Mix.Tasks.Pleroma.Relay do
use Mix.Task use Mix.Task
import Mix.Pleroma import Mix.Pleroma
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Relay
@shortdoc "Manages remote relays" @shortdoc "Manages remote relays"
...@@ -36,13 +35,10 @@ def run(["unfollow", target]) do ...@@ -36,13 +35,10 @@ def run(["unfollow", target]) do
def run(["list"]) do def run(["list"]) do
start_pleroma() start_pleroma()
with %User{following: following} = _user <- Relay.get_actor() do with {:ok, list} <- Relay.list() do
following list |> Enum.each(&shell_info(&1))
|> Enum.map(fn entry -> URI.parse(entry).host end)
|> Enum.uniq()
|> Enum.each(&shell_info(&1))
else 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 end
end end
...@@ -51,6 +51,20 @@ def publish(%Activity{data: %{"type" => "Create"}} = activity) do ...@@ -51,6 +51,20 @@ def publish(%Activity{data: %{"type" => "Create"}} = activity) do
def publish(_), do: {:error, "Not implemented"} 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, error}), do: format_error(error)
defp format_error(error) do defp format_error(error) do
......
...@@ -481,6 +481,16 @@ def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" ...@@ -481,6 +481,16 @@ def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname"
render_error(conn, :forbidden, "You can't revoke your own admin status.") render_error(conn, :forbidden, "You can't revoke your own admin status.")
end 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 def relay_follow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target}) do
with {:ok, _message} <- Relay.follow(target) do with {:ok, _message} <- Relay.follow(target) do
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
......
...@@ -161,6 +161,7 @@ defmodule Pleroma.Web.Router do ...@@ -161,6 +161,7 @@ defmodule Pleroma.Web.Router do
:right_delete_multiple :right_delete_multiple
) )
get("/relay", AdminAPIController, :relay_list)
post("/relay", AdminAPIController, :relay_follow) post("/relay", AdminAPIController, :relay_follow)
delete("/relay", AdminAPIController, :relay_unfollow) delete("/relay", AdminAPIController, :relay_unfollow)
......
...@@ -17,6 +17,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ...@@ -17,6 +17,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
import Pleroma.Factory 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 describe "DELETE /api/pleroma/admin/users" do
test "single user" do test "single user" do
admin = insert(:user, info: %{is_admin: true}) admin = insert(:user, info: %{is_admin: true})
...@@ -2541,6 +2547,74 @@ test "sets password_reset_pending to true", %{admin: admin, user: user} do ...@@ -2541,6 +2547,74 @@ test "sets password_reset_pending to true", %{admin: admin, user: user} do
assert User.get_by_id(user.id).info.password_reset_pending == true assert User.get_by_id(user.id).info.password_reset_pending == true
end end
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 end
# Needed for testing # Needed for testing
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment