Make notifs view work for reports

* These are the first small steps for issue 2034 "Reports should send a notification to admins".
* I added a new type of notification "pleroma:report" to the the database manually (a migration will need to be written later)
* I added the new type to the notification_controller
* I made the view return the notification. It doesn't include the report itself (yet)
This commit is contained in:
Ilja 2020-11-13 13:35:46 +00:00 committed by lain
parent 294628d981
commit 70e4b86250
9 changed files with 155 additions and 3 deletions

View File

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mix task for sending confirmation emails to all unconfirmed users (`mix pleroma.email send_confirmation_mails`) - Mix task for sending confirmation emails to all unconfirmed users (`mix pleroma.email send_confirmation_mails`)
- Mix task option for force-unfollowing relays - Mix task option for force-unfollowing relays
- Media preview proxy (requires `ffmpeg` and `ImageMagick` to be installed and media proxy to be enabled; see `:media_preview_proxy` config for more details). - Media preview proxy (requires `ffmpeg` and `ImageMagick` to be installed and media proxy to be enabled; see `:media_preview_proxy` config for more details).
- Reports now generate notifications for admins and mods.
- Pleroma API: Importing the mutes users from CSV files. - Pleroma API: Importing the mutes users from CSV files.
- Experimental websocket-based federation between Pleroma instances. - Experimental websocket-based federation between Pleroma instances.
- Support pagination of blocks and mutes - Support pagination of blocks and mutes

View File

@ -129,12 +129,30 @@ The `type` value is `pleroma:emoji_reaction`. Has these fields:
- `account`: The account of the user who reacted - `account`: The account of the user who reacted
- `status`: The status that was reacted on - `status`: The status that was reacted on
### ChatMention Notification (not default)
This notification has to be requested explicitly.
The `type` value is `pleroma:chat_mention`
- `account`: The account who sent the message
- `chat_message`: The chat message
### Report Notification (not default)
This notification has to be requested explicitly.
The `type` value is `pleroma:report`
- `account`: The account who reported
- `report`: The report
## GET `/api/v1/notifications` ## GET `/api/v1/notifications`
Accepts additional parameters: Accepts additional parameters:
- `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`. - `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`.
- `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`. - `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`, `pleroma:chat_mention`, `pleroma:report`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`.
## DELETE `/api/v1/notifications/destroy_multiple` ## DELETE `/api/v1/notifications/destroy_multiple`

View File

@ -70,6 +70,7 @@ defmodule Pleroma.Notification do
move move
pleroma:chat_mention pleroma:chat_mention
pleroma:emoji_reaction pleroma:emoji_reaction
pleroma:report
reblog reblog
} }
@ -367,7 +368,7 @@ defmodule Pleroma.Notification do
end end
def create_notifications(%Activity{data: %{"type" => type}} = activity, options) def create_notifications(%Activity{data: %{"type" => type}} = activity, options)
when type in ["Follow", "Like", "Announce", "Move", "EmojiReact"] do when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag"] do
do_create_notifications(activity, options) do_create_notifications(activity, options)
end end
@ -410,6 +411,9 @@ defmodule Pleroma.Notification do
"EmojiReact" -> "EmojiReact" ->
"pleroma:emoji_reaction" "pleroma:emoji_reaction"
"Flag" ->
"pleroma:report"
# Compatibility with old reactions # Compatibility with old reactions
"EmojiReaction" -> "EmojiReaction" ->
"pleroma:emoji_reaction" "pleroma:emoji_reaction"
@ -467,7 +471,7 @@ defmodule Pleroma.Notification do
def get_notified_from_activity(activity, local_only \\ true) def get_notified_from_activity(activity, local_only \\ true)
def get_notified_from_activity(%Activity{data: %{"type" => type}} = activity, local_only) def get_notified_from_activity(%Activity{data: %{"type" => type}} = activity, local_only)
when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact"] do when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact", "Flag"] do
potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity) potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity)
potential_receivers = potential_receivers =
@ -503,6 +507,10 @@ defmodule Pleroma.Notification do
[object_id] [object_id]
end end
def get_potential_receiver_ap_ids(%{data: %{"type" => "Flag"}}) do
User.all_superusers() |> Enum.map(fn user -> user.ap_id end)
end
def get_potential_receiver_ap_ids(activity) do def get_potential_receiver_ap_ids(activity) do
[] []
|> Utils.maybe_notify_to_recipients(activity) |> Utils.maybe_notify_to_recipients(activity)

View File

@ -193,6 +193,7 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
"mention", "mention",
"pleroma:emoji_reaction", "pleroma:emoji_reaction",
"pleroma:chat_mention", "pleroma:chat_mention",
"pleroma:report",
"move", "move",
"follow_request" "follow_request"
], ],
@ -206,6 +207,8 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
- `poll` - A poll you have voted in or created has ended - `poll` - A poll you have voted in or created has ended
- `move` - Someone moved their account - `move` - Someone moved their account
- `pleroma:emoji_reaction` - Someone reacted with emoji to your status - `pleroma:emoji_reaction` - Someone reacted with emoji to your status
- `pleroma:chat_mention` - Someone mentioned you in a chat message
- `pleroma:report` - Someone was reported
""" """
} }
end end

View File

@ -11,6 +11,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.User alias Pleroma.User
alias Pleroma.UserRelationship alias Pleroma.UserRelationship
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.AdminAPI.ReportView
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.NotificationView alias Pleroma.Web.MastodonAPI.NotificationView
@ -118,11 +120,20 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
"pleroma:chat_mention" -> "pleroma:chat_mention" ->
put_chat_message(response, activity, reading_user, status_render_opts) put_chat_message(response, activity, reading_user, status_render_opts)
"pleroma:report" ->
put_report(response, activity)
type when type in ["follow", "follow_request"] -> type when type in ["follow", "follow_request"] ->
response response
end end
end end
defp put_report(response, activity) do
report_render = ReportView.render("show.json", Report.extract_report_info(activity))
Map.put(response, :report, report_render)
end
defp put_emoji(response, activity) do defp put_emoji(response, activity) do
Map.put(response, :emoji, activity.data["content"]) Map.put(response, :emoji, activity.data["content"])
end end

View File

@ -0,0 +1,48 @@
defmodule Pleroma.Repo.Migrations.AddPleromaReportTypeToEnumForNotifications do
use Ecto.Migration
@disable_ddl_transaction true
def up do
"""
alter type notification_type add value 'pleroma:report'
"""
|> execute()
end
def down do
alter table(:notifications) do
modify(:type, :string)
end
"""
delete from notifications where type = 'pleroma:report'
"""
|> execute()
"""
drop type if exists notification_type
"""
|> execute()
"""
create type notification_type as enum (
'follow',
'follow_request',
'mention',
'move',
'pleroma:emoji_reaction',
'pleroma:chat_mention',
'reblog',
'favourite'
)
"""
|> execute()
"""
alter table notifications
alter column type type notification_type using (type::notification_type)
"""
|> execute()
end
end

View File

@ -32,6 +32,19 @@ defmodule Pleroma.NotificationTest do
refute {:ok, [nil]} == Notification.create_notifications(activity) refute {:ok, [nil]} == Notification.create_notifications(activity)
end end
test "creates a notification for a report" do
reporting_user = insert(:user)
reported_user = insert(:user)
{:ok, moderator_user} = insert(:user) |> User.admin_api_update(%{is_moderator: true})
{:ok, activity} = CommonAPI.report(reporting_user, %{account_id: reported_user.id})
{:ok, [notification]} = Notification.create_notifications(activity)
assert notification.user_id == moderator_user.id
assert notification.type == "pleroma:report"
end
test "creates a notification for an emoji reaction" do test "creates a notification for an emoji reaction" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)

View File

@ -75,6 +75,34 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
assert [_] = result assert [_] = result
end end
test "by default, does not contain pleroma:report" do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user)
third_user = insert(:user)
user
|> User.admin_api_update(%{is_moderator: true})
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
{:ok, _report} =
CommonAPI.report(third_user, %{account_id: other_user.id, status_ids: [activity.id]})
result =
conn
|> get("/api/v1/notifications")
|> json_response_and_validate_schema(200)
assert [] == result
result =
conn
|> get("/api/v1/notifications?include_types[]=pleroma:report")
|> json_response_and_validate_schema(200)
assert [_] = result
end
test "getting a single notification" do test "getting a single notification" do
%{user: user, conn: conn} = oauth_access(["read:notifications"]) %{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user) other_user = insert(:user)

View File

@ -12,6 +12,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.AdminAPI.ReportView
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
@ -207,6 +209,26 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], user, [expected]) test_notifications_rendering([notification], user, [expected])
end end
test "Report notification" do
reporting_user = insert(:user)
reported_user = insert(:user)
{:ok, moderator_user} = insert(:user) |> User.admin_api_update(%{is_moderator: true})
{:ok, activity} = CommonAPI.report(reporting_user, %{account_id: reported_user.id})
{:ok, [notification]} = Notification.create_notifications(activity)
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false, is_muted: false},
type: "pleroma:report",
account: AccountView.render("show.json", %{user: reporting_user, for: moderator_user}),
created_at: Utils.to_masto_date(notification.inserted_at),
report: ReportView.render("show.json", Report.extract_report_info(activity))
}
test_notifications_rendering([notification], moderator_user, [expected])
end
test "muted notification" do test "muted notification" do
user = insert(:user) user = insert(:user)
another_user = insert(:user) another_user = insert(:user)