Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop

This commit is contained in:
sadposter 2020-04-21 00:24:32 +01:00
commit 1504211101
21 changed files with 421 additions and 193 deletions

View file

@ -13,6 +13,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses. - Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
- New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma wont start. For hackney OTP update is not required. - New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma wont start. For hackney OTP update is not required.
- Mix task to create trusted OAuth App. - Mix task to create trusted OAuth App.
- Notifications: Added `follow_request` notification type (configurable, see `[:notifications, :enable_follow_request_notifications]` setting).
- Added `:reject_deletes` group to SimplePolicy
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
- Mastodon API: Support for `include_types` in `/api/v1/notifications`. - Mastodon API: Support for `include_types` in `/api/v1/notifications`.
@ -22,13 +24,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed ### Fixed
- Support pagination in conversations API - Support pagination in conversations API
- **Breaking**: SimplePolicy `:reject` and `:accept` allow deletions again
## [unreleased-patch] ## [unreleased-patch]
### Fixed ### Fixed
- Logger configuration through AdminFE - Logger configuration through AdminFE
- HTTP Basic Authentication permissions issue - HTTP Basic Authentication permissions issue
- ObjectAgePolicy didn't filter out old messages
### Added ### Added
- NodeInfo: ObjectAgePolicy settings to the `federation` list.
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
- Admin API: `GET /api/pleroma/admin/need_reboot`. - Admin API: `GET /api/pleroma/admin/need_reboot`.

View file

@ -337,7 +337,8 @@
reject: [], reject: [],
accept: [], accept: [],
avatar_removal: [], avatar_removal: [],
banner_removal: [] banner_removal: [],
reject_deletes: []
config :pleroma, :mrf_keyword, config :pleroma, :mrf_keyword,
reject: [], reject: [],
@ -562,6 +563,8 @@
inactivity_threshold: 7 inactivity_threshold: 7
} }
config :pleroma, :notifications, enable_follow_request_notifications: false
config :pleroma, :oauth2, config :pleroma, :oauth2,
token_expires_in: 600, token_expires_in: 600,
issue_new_refresh_token: true, issue_new_refresh_token: true,

View file

@ -1317,13 +1317,13 @@
%{ %{
key: :reject, key: :reject,
type: {:list, :string}, type: {:list, :string},
description: "List of instances to reject any activities from", description: "List of instances to reject activities from (except deletes)",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
}, },
%{ %{
key: :accept, key: :accept,
type: {:list, :string}, type: {:list, :string},
description: "List of instances to accept any activities from", description: "List of instances to only accept activities from (except deletes)",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
}, },
%{ %{
@ -1343,6 +1343,12 @@
type: {:list, :string}, type: {:list, :string},
description: "List of instances to strip banners from", description: "List of instances to strip banners from",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
},
%{
key: :reject_deletes,
type: {:list, :string},
description: "List of instances to reject deletions from",
suggestions: ["example.com", "*.example.com"]
} }
] ]
}, },
@ -2267,6 +2273,20 @@
} }
] ]
}, },
%{
group: :pleroma,
key: :notifications,
type: :group,
description: "Notification settings",
children: [
%{
key: :enable_follow_request_notifications,
type: :boolean,
description:
"Enables notifications on new follow requests (causes issues with older PleromaFE versions)."
}
]
},
%{ %{
group: :pleroma, group: :pleroma,
key: Pleroma.Emails.UserEmail, key: Pleroma.Emails.UserEmail,

View file

@ -41,11 +41,15 @@ config :pleroma, :instance,
Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are: Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are:
* `media_removal`: Servers in this group will have media stripped from incoming messages.
* `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media.
* `reject`: Servers in this group will have their messages rejected. * `reject`: Servers in this group will have their messages rejected.
* `federated_timeline_removal`: Servers in this group will have their messages unlisted from the public timelines by flipping the `to` and `cc` fields. * `accept`: If not empty, only messages from these instances will be accepted (whitelist federation).
* `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media.
* `media_removal`: Servers in this group will have media stripped from incoming messages.
* `avatar_removal`: Avatars from these servers will be stripped from incoming messages.
* `banner_removal`: Banner images from these servers will be stripped from incoming messages.
* `report_removal`: Servers in this group will have their reports (flags) rejected. * `report_removal`: Servers in this group will have their reports (flags) rejected.
* `federated_timeline_removal`: Servers in this group will have their messages unlisted from the public timelines by flipping the `to` and `cc` fields.
* `reject_deletes`: Deletion requests will be rejected from these servers.
Servers should be configured as lists. Servers should be configured as lists.

View file

@ -27,17 +27,13 @@ defmodule Pleroma.Activity do
# https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19 # https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19
@mastodon_notification_types %{ @mastodon_notification_types %{
"Create" => "mention", "Create" => "mention",
"Follow" => "follow", "Follow" => ["follow", "follow_request"],
"Announce" => "reblog", "Announce" => "reblog",
"Like" => "favourite", "Like" => "favourite",
"Move" => "move", "Move" => "move",
"EmojiReact" => "pleroma:emoji_reaction" "EmojiReact" => "pleroma:emoji_reaction"
} }
@mastodon_to_ap_notification_types for {k, v} <- @mastodon_notification_types,
into: %{},
do: {v, k}
schema "activities" do schema "activities" do
field(:data, :map) field(:data, :map)
field(:local, :boolean, default: true) field(:local, :boolean, default: true)
@ -291,15 +287,43 @@ defp purge_web_resp_cache(%Activity{} = activity) do
defp purge_web_resp_cache(nil), do: nil defp purge_web_resp_cache(nil), do: nil
for {ap_type, type} <- @mastodon_notification_types do def follow_accepted?(
%Activity{data: %{"type" => "Follow", "object" => followed_ap_id}} = activity
) do
with %User{} = follower <- Activity.user_actor(activity),
%User{} = followed <- User.get_cached_by_ap_id(followed_ap_id) do
Pleroma.FollowingRelationship.following?(follower, followed)
else
_ -> false
end
end
def follow_accepted?(_), do: false
@spec mastodon_notification_type(Activity.t()) :: String.t() | nil
for {ap_type, type} <- @mastodon_notification_types, not is_list(type) do
def mastodon_notification_type(%Activity{data: %{"type" => unquote(ap_type)}}), def mastodon_notification_type(%Activity{data: %{"type" => unquote(ap_type)}}),
do: unquote(type) do: unquote(type)
end end
def mastodon_notification_type(%Activity{data: %{"type" => "Follow"}} = activity) do
if follow_accepted?(activity) do
"follow"
else
"follow_request"
end
end
def mastodon_notification_type(%Activity{}), do: nil def mastodon_notification_type(%Activity{}), do: nil
@spec from_mastodon_notification_type(String.t()) :: String.t() | nil
@doc "Converts Mastodon notification type to AR activity type"
def from_mastodon_notification_type(type) do def from_mastodon_notification_type(type) do
Map.get(@mastodon_to_ap_notification_types, type) with {k, _v} <-
Enum.find(@mastodon_notification_types, fn {_k, v} -> type in List.wrap(v) end) do
k
end
end end
def all_by_actor_and_id(actor, status_ids \\ []) def all_by_actor_and_id(actor, status_ids \\ [])

View file

@ -284,8 +284,17 @@ def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = act
end end
end end
def create_notifications(%Activity{data: %{"type" => "Follow"}} = activity) do
if Pleroma.Config.get([:notifications, :enable_follow_request_notifications]) ||
Activity.follow_accepted?(activity) do
do_create_notifications(activity)
else
{:ok, []}
end
end
def create_notifications(%Activity{data: %{"type" => type}} = activity) def create_notifications(%Activity{data: %{"type" => type}} = activity)
when type in ["Like", "Announce", "Follow", "Move", "EmojiReact"] do when type in ["Like", "Announce", "Move", "EmojiReact"] do
do_create_notifications(activity) do_create_notifications(activity)
end end

View file

@ -688,6 +688,8 @@ def needs_update?(%User{local: false} = user) do
def needs_update?(_), do: true def needs_update?(_), do: true
@spec maybe_direct_follow(User.t(), User.t()) :: {:ok, User.t()} | {:error, String.t()} @spec maybe_direct_follow(User.t(), User.t()) :: {:ok, User.t()} | {:error, String.t()}
# "Locked" (self-locked) users demand explicit authorization of follow requests
def maybe_direct_follow(%User{} = follower, %User{local: true, locked: true} = followed) do def maybe_direct_follow(%User{} = follower, %User{local: true, locked: true} = followed) do
follow(follower, followed, :follow_pending) follow(follower, followed, :follow_pending)
end end

View file

@ -11,7 +11,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
@moduledoc "Filter activities depending on their age" @moduledoc "Filter activities depending on their age"
@behaviour Pleroma.Web.ActivityPub.MRF @behaviour Pleroma.Web.ActivityPub.MRF
defp check_date(%{"published" => published} = message) do defp check_date(%{"object" => %{"published" => published}} = message) do
with %DateTime{} = now <- DateTime.utc_now(), with %DateTime{} = now <- DateTime.utc_now(),
{:ok, %DateTime{} = then, _} <- DateTime.from_iso8601(published), {:ok, %DateTime{} = then, _} <- DateTime.from_iso8601(published),
max_ttl <- Config.get([:mrf_object_age, :threshold]), max_ttl <- Config.get([:mrf_object_age, :threshold]),
@ -96,5 +96,11 @@ def filter(%{"type" => "Create", "published" => _} = message) do
def filter(message), do: {:ok, message} def filter(message), do: {:ok, message}
@impl true @impl true
def describe, do: {:ok, %{}} def describe do
mrf_object_age =
Pleroma.Config.get(:mrf_object_age)
|> Enum.into(%{})
{:ok, %{mrf_object_age: mrf_object_age}}
end
end end

View file

@ -148,6 +148,21 @@ defp check_banner_removal(%{host: actor_host} = _actor_info, %{"image" => _image
defp check_banner_removal(_actor_info, object), do: {:ok, object} defp check_banner_removal(_actor_info, object), do: {:ok, object}
@impl true
def filter(%{"type" => "Delete", "actor" => actor} = object) do
%{host: actor_host} = URI.parse(actor)
reject_deletes =
Pleroma.Config.get([:mrf_simple, :reject_deletes])
|> MRF.subdomains_regex()
if MRF.subdomain_match?(reject_deletes, actor_host) do
{:reject, nil}
else
{:ok, object}
end
end
@impl true @impl true
def filter(%{"actor" => actor} = object) do def filter(%{"actor" => actor} = object) do
actor_info = URI.parse(actor) actor_info = URI.parse(actor)

View file

@ -6,25 +6,22 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionController do
@moduledoc "The module represents functions to manage user subscriptions." @moduledoc "The module represents functions to manage user subscriptions."
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View
alias Pleroma.Web.Push alias Pleroma.Web.Push
alias Pleroma.Web.Push.Subscription alias Pleroma.Web.Push.Subscription
action_fallback(:errors) action_fallback(:errors)
plug(Pleroma.Plugs.OAuthScopesPlug, %{scopes: ["push"]}) plug(Pleroma.Plugs.OAuthScopesPlug, %{scopes: ["push"]})
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug) plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
plug(:restrict_push_enabled)
# Creates PushSubscription # Creates PushSubscription
# POST /api/v1/push/subscription # POST /api/v1/push/subscription
# #
def create(%{assigns: %{user: user, token: token}} = conn, params) do def create(%{assigns: %{user: user, token: token}} = conn, params) do
with true <- Push.enabled(), with {:ok, _} <- Subscription.delete_if_exists(user, token),
{:ok, _} <- Subscription.delete_if_exists(user, token),
{:ok, subscription} <- Subscription.create(user, token, params) do {:ok, subscription} <- Subscription.create(user, token, params) do
view = View.render("push_subscription.json", subscription: subscription) render(conn, "show.json", subscription: subscription)
json(conn, view)
end end
end end
@ -32,10 +29,8 @@ def create(%{assigns: %{user: user, token: token}} = conn, params) do
# GET /api/v1/push/subscription # GET /api/v1/push/subscription
# #
def get(%{assigns: %{user: user, token: token}} = conn, _params) do def get(%{assigns: %{user: user, token: token}} = conn, _params) do
with true <- Push.enabled(), with {:ok, subscription} <- Subscription.get(user, token) do
{:ok, subscription} <- Subscription.get(user, token) do render(conn, "show.json", subscription: subscription)
view = View.render("push_subscription.json", subscription: subscription)
json(conn, view)
end end
end end
@ -43,10 +38,8 @@ def get(%{assigns: %{user: user, token: token}} = conn, _params) do
# PUT /api/v1/push/subscription # PUT /api/v1/push/subscription
# #
def update(%{assigns: %{user: user, token: token}} = conn, params) do def update(%{assigns: %{user: user, token: token}} = conn, params) do
with true <- Push.enabled(), with {:ok, subscription} <- Subscription.update(user, token, params) do
{:ok, subscription} <- Subscription.update(user, token, params) do render(conn, "show.json", subscription: subscription)
view = View.render("push_subscription.json", subscription: subscription)
json(conn, view)
end end
end end
@ -54,11 +47,20 @@ def update(%{assigns: %{user: user, token: token}} = conn, params) do
# DELETE /api/v1/push/subscription # DELETE /api/v1/push/subscription
# #
def delete(%{assigns: %{user: user, token: token}} = conn, _params) do def delete(%{assigns: %{user: user, token: token}} = conn, _params) do
with true <- Push.enabled(), with {:ok, _response} <- Subscription.delete(user, token),
{:ok, _response} <- Subscription.delete(user, token),
do: json(conn, %{}) do: json(conn, %{})
end end
defp restrict_push_enabled(conn, _) do
if Push.enabled() do
conn
else
conn
|> render_error(:forbidden, "Web push subscription is disabled on this Pleroma instance")
|> halt()
end
end
# fallback action # fallback action
# #
def errors(conn, {:error, :not_found}) do def errors(conn, {:error, :not_found}) do

View file

@ -117,14 +117,14 @@ def render(
# Note: :skip_relationships option being applied to _account_ rendering (here) # Note: :skip_relationships option being applied to _account_ rendering (here)
put_target(response, activity, reading_user, render_opts) put_target(response, activity, reading_user, render_opts)
"follow" ->
response
"pleroma:emoji_reaction" -> "pleroma:emoji_reaction" ->
response response
|> put_status(parent_activity_fn.(), reading_user, render_opts) |> put_status(parent_activity_fn.(), reading_user, render_opts)
|> put_emoji(activity) |> put_emoji(activity)
type when type in ["follow", "follow_request"] ->
response
_ -> _ ->
nil nil
end end

View file

@ -2,11 +2,11 @@
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.PushSubscriptionView do defmodule Pleroma.Web.MastodonAPI.SubscriptionView do
use Pleroma.Web, :view use Pleroma.Web, :view
alias Pleroma.Web.Push alias Pleroma.Web.Push
def render("push_subscription.json", %{subscription: subscription}) do def render("show.json", %{subscription: subscription}) do
%{ %{
id: to_string(subscription.id), id: to_string(subscription.id),
endpoint: subscription.endpoint, endpoint: subscription.endpoint,

View file

@ -16,6 +16,8 @@ defmodule Pleroma.Web.Push.Impl do
require Logger require Logger
import Ecto.Query import Ecto.Query
defdelegate mastodon_notification_type(activity), to: Activity
@types ["Create", "Follow", "Announce", "Like", "Move"] @types ["Create", "Follow", "Announce", "Like", "Move"]
@doc "Performs sending notifications for user subscriptions" @doc "Performs sending notifications for user subscriptions"
@ -24,32 +26,32 @@ def perform(
%{ %{
activity: %{data: %{"type" => activity_type}} = activity, activity: %{data: %{"type" => activity_type}} = activity,
user: %User{id: user_id} user: %User{id: user_id}
} = notif } = notification
) )
when activity_type in @types do when activity_type in @types do
actor = User.get_cached_by_ap_id(notif.activity.data["actor"]) actor = User.get_cached_by_ap_id(notification.activity.data["actor"])
type = Activity.mastodon_notification_type(notif.activity) mastodon_type = mastodon_notification_type(notification.activity)
gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key) gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key)
avatar_url = User.avatar_url(actor) avatar_url = User.avatar_url(actor)
object = Object.normalize(activity) object = Object.normalize(activity)
user = User.get_cached_by_id(user_id) user = User.get_cached_by_id(user_id)
direct_conversation_id = Activity.direct_conversation_id(activity, user) direct_conversation_id = Activity.direct_conversation_id(activity, user)
for subscription <- fetch_subsriptions(user_id), for subscription <- fetch_subscriptions(user_id),
get_in(subscription.data, ["alerts", type]) do Subscription.enabled?(subscription, mastodon_type) do
%{ %{
access_token: subscription.token.token, access_token: subscription.token.token,
notification_id: notif.id, notification_id: notification.id,
notification_type: type, notification_type: mastodon_type,
icon: avatar_url, icon: avatar_url,
preferred_locale: "en", preferred_locale: "en",
pleroma: %{ pleroma: %{
activity_id: notif.activity.id, activity_id: notification.activity.id,
direct_conversation_id: direct_conversation_id direct_conversation_id: direct_conversation_id
} }
} }
|> Map.merge(build_content(notif, actor, object)) |> Map.merge(build_content(notification, actor, object, mastodon_type))
|> Jason.encode!() |> Jason.encode!()
|> push_message(build_sub(subscription), gcm_api_key, subscription) |> push_message(build_sub(subscription), gcm_api_key, subscription)
end end
@ -82,7 +84,7 @@ def push_message(body, sub, api_key, subscription) do
end end
@doc "Gets user subscriptions" @doc "Gets user subscriptions"
def fetch_subsriptions(user_id) do def fetch_subscriptions(user_id) do
Subscription Subscription
|> where(user_id: ^user_id) |> where(user_id: ^user_id)
|> preload(:token) |> preload(:token)
@ -99,28 +101,36 @@ def build_sub(subscription) do
} }
end end
def build_content(notification, actor, object, mastodon_type \\ nil)
def build_content( def build_content(
%{ %{
activity: %{data: %{"directMessage" => true}}, activity: %{data: %{"directMessage" => true}},
user: %{notification_settings: %{privacy_option: true}} user: %{notification_settings: %{privacy_option: true}}
}, },
actor, actor,
_ _object,
_mastodon_type
) do ) do
%{title: "New Direct Message", body: "@#{actor.nickname}"} %{title: "New Direct Message", body: "@#{actor.nickname}"}
end end
def build_content(notif, actor, object) do def build_content(notification, actor, object, mastodon_type) do
mastodon_type = mastodon_type || mastodon_notification_type(notification.activity)
%{ %{
title: format_title(notif), title: format_title(notification, mastodon_type),
body: format_body(notif, actor, object) body: format_body(notification, actor, object, mastodon_type)
} }
end end
def format_body(activity, actor, object, mastodon_type \\ nil)
def format_body( def format_body(
%{activity: %{data: %{"type" => "Create"}}}, %{activity: %{data: %{"type" => "Create"}}},
actor, actor,
%{data: %{"content" => content}} %{data: %{"content" => content}},
_mastodon_type
) do ) do
"@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}"
end end
@ -128,33 +138,44 @@ def format_body(
def format_body( def format_body(
%{activity: %{data: %{"type" => "Announce"}}}, %{activity: %{data: %{"type" => "Announce"}}},
actor, actor,
%{data: %{"content" => content}} %{data: %{"content" => content}},
_mastodon_type
) do ) do
"@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" "@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}"
end end
def format_body( def format_body(
%{activity: %{data: %{"type" => type}}}, %{activity: %{data: %{"type" => type}}} = notification,
actor, actor,
_object _object,
mastodon_type
) )
when type in ["Follow", "Like"] do when type in ["Follow", "Like"] do
case type do mastodon_type = mastodon_type || mastodon_notification_type(notification.activity)
"Follow" -> "@#{actor.nickname} has followed you"
"Like" -> "@#{actor.nickname} has favorited your post" case mastodon_type do
"follow" -> "@#{actor.nickname} has followed you"
"follow_request" -> "@#{actor.nickname} has requested to follow you"
"favourite" -> "@#{actor.nickname} has favorited your post"
end end
end end
def format_title(%{activity: %{data: %{"directMessage" => true}}}) do def format_title(activity, mastodon_type \\ nil)
def format_title(%{activity: %{data: %{"directMessage" => true}}}, _mastodon_type) do
"New Direct Message" "New Direct Message"
end end
def format_title(%{activity: %{data: %{"type" => type}}}) do def format_title(%{activity: activity}, mastodon_type) do
case type do mastodon_type = mastodon_type || mastodon_notification_type(activity)
"Create" -> "New Mention"
"Follow" -> "New Follower" case mastodon_type do
"Announce" -> "New Repeat" "mention" -> "New Mention"
"Like" -> "New Favorite" "follow" -> "New Follower"
"follow_request" -> "New Follow Request"
"reblog" -> "New Repeat"
"favourite" -> "New Favorite"
type -> "New #{String.capitalize(type || "event")}"
end end
end end
end end

View file

@ -32,6 +32,14 @@ defp alerts(%{"data" => %{"alerts" => alerts}}) do
%{"alerts" => alerts} %{"alerts" => alerts}
end end
def enabled?(subscription, "follow_request") do
enabled?(subscription, "follow")
end
def enabled?(subscription, alert_type) do
get_in(subscription.data, ["alerts", alert_type])
end
def create( def create(
%User{} = user, %User{} = user,
%Token{} = token, %Token{} = token,

View file

@ -16,79 +16,60 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Plugs.UserEnabledPlug) plug(Pleroma.Plugs.UserEnabledPlug)
end end
pipeline :api do pipeline :authenticate do
plug(:accepts, ["json"])
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug) plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug) plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug) plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug) plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug) plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug) plug(Pleroma.Plugs.AuthenticationPlug)
end
pipeline :after_auth do
plug(Pleroma.Plugs.UserEnabledPlug) plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug) plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug) plug(Pleroma.Plugs.EnsureUserKeyPlug)
plug(Pleroma.Plugs.IdempotencyPlug) end
pipeline :base_api do
plug(:accepts, ["json"])
plug(:fetch_session)
plug(:authenticate)
plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec) plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
end end
pipeline :api do
plug(:base_api)
plug(:after_auth)
plug(Pleroma.Plugs.IdempotencyPlug)
end
pipeline :authenticated_api do pipeline :authenticated_api do
plug(:accepts, ["json"]) plug(:base_api)
plug(:fetch_session)
plug(Pleroma.Plugs.AuthExpectedPlug) plug(Pleroma.Plugs.AuthExpectedPlug)
plug(Pleroma.Plugs.OAuthPlug) plug(:after_auth)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureAuthenticatedPlug) plug(Pleroma.Plugs.EnsureAuthenticatedPlug)
plug(Pleroma.Plugs.IdempotencyPlug) plug(Pleroma.Plugs.IdempotencyPlug)
plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
end end
pipeline :admin_api do pipeline :admin_api do
plug(:accepts, ["json"]) plug(:base_api)
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.AdminSecretAuthenticationPlug) plug(Pleroma.Plugs.AdminSecretAuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug) plug(:after_auth)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureAuthenticatedPlug) plug(Pleroma.Plugs.EnsureAuthenticatedPlug)
plug(Pleroma.Plugs.UserIsAdminPlug) plug(Pleroma.Plugs.UserIsAdminPlug)
plug(Pleroma.Plugs.IdempotencyPlug) plug(Pleroma.Plugs.IdempotencyPlug)
plug(OpenApiSpex.Plug.PutApiSpec, module: Pleroma.Web.ApiSpec)
end end
pipeline :mastodon_html do pipeline :mastodon_html do
plug(:accepts, ["html"]) plug(:browser)
plug(:fetch_session) plug(:authenticate)
plug(Pleroma.Plugs.OAuthPlug) plug(:after_auth)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug)
end end
pipeline :pleroma_html do pipeline :pleroma_html do
plug(:accepts, ["html"]) plug(:browser)
plug(:fetch_session) plug(:authenticate)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug) plug(Pleroma.Plugs.EnsureUserKeyPlug)
end end
@ -515,7 +496,7 @@ defmodule Pleroma.Web.Router do
end end
scope "/api" do scope "/api" do
pipe_through(:api) pipe_through(:base_api)
get("/openapi", OpenApiSpex.Plug.RenderSpec, []) get("/openapi", OpenApiSpex.Plug.RenderSpec, [])
end end
@ -529,10 +510,6 @@ defmodule Pleroma.Web.Router do
post("/qvitter/statuses/notifications/read", TwitterAPI.Controller, :notifications_read) post("/qvitter/statuses/notifications/read", TwitterAPI.Controller, :notifications_read)
end end
pipeline :ap_service_actor do
plug(:accepts, ["activity+json", "json"])
end
pipeline :ostatus do pipeline :ostatus do
plug(:accepts, ["html", "xml", "rss", "atom", "activity+json", "json"]) plug(:accepts, ["html", "xml", "rss", "atom", "activity+json", "json"])
plug(Pleroma.Plugs.StaticFEPlug) plug(Pleroma.Plugs.StaticFEPlug)
@ -543,8 +520,7 @@ defmodule Pleroma.Web.Router do
end end
scope "/", Pleroma.Web do scope "/", Pleroma.Web do
pipe_through(:ostatus) pipe_through([:ostatus, :http_signature])
pipe_through(:http_signature)
get("/objects/:uuid", OStatus.OStatusController, :object) get("/objects/:uuid", OStatus.OStatusController, :object)
get("/activities/:uuid", OStatus.OStatusController, :activity) get("/activities/:uuid", OStatus.OStatusController, :activity)
@ -562,13 +538,6 @@ defmodule Pleroma.Web.Router do
get("/mailer/unsubscribe/:token", Mailer.SubscriptionController, :unsubscribe) get("/mailer/unsubscribe/:token", Mailer.SubscriptionController, :unsubscribe)
end end
# Server to Server (S2S) AP interactions
pipeline :activitypub do
plug(:accepts, ["activity+json", "json"])
plug(Pleroma.Web.Plugs.HTTPSignaturePlug)
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
end
scope "/", Pleroma.Web.ActivityPub do scope "/", Pleroma.Web.ActivityPub do
# XXX: not really ostatus # XXX: not really ostatus
pipe_through(:ostatus) pipe_through(:ostatus)
@ -576,19 +545,22 @@ defmodule Pleroma.Web.Router do
get("/users/:nickname/outbox", ActivityPubController, :outbox) get("/users/:nickname/outbox", ActivityPubController, :outbox)
end end
pipeline :ap_service_actor do
plug(:accepts, ["activity+json", "json"])
end
# Server to Server (S2S) AP interactions
pipeline :activitypub do
plug(:ap_service_actor)
plug(:http_signature)
end
# Client to Server (C2S) AP interactions # Client to Server (C2S) AP interactions
pipeline :activitypub_client do pipeline :activitypub_client do
plug(:accepts, ["activity+json", "json"]) plug(:ap_service_actor)
plug(:fetch_session) plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug) plug(:authenticate)
plug(Pleroma.Plugs.BasicAuthDecoderPlug) plug(:after_auth)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug)
end end
scope "/", Pleroma.Web.ActivityPub do scope "/", Pleroma.Web.ActivityPub do
@ -660,12 +632,7 @@ defmodule Pleroma.Web.Router do
get("/web/*path", MastoFEController, :index) get("/web/*path", MastoFEController, :index)
end end
pipeline :remote_media do
end
scope "/proxy/", Pleroma.Web.MediaProxy do scope "/proxy/", Pleroma.Web.MediaProxy do
pipe_through(:remote_media)
get("/:sig/:url", MediaProxyController, :remote) get("/:sig/:url", MediaProxyController, :remote)
get("/:sig/:url/:filename", MediaProxyController, :remote) get("/:sig/:url/:filename", MediaProxyController, :remote)
end end

21
mix.exs
View file

@ -221,19 +221,26 @@ defp version(version) do
identifier_filter = ~r/[^0-9a-z\-]+/i identifier_filter = ~r/[^0-9a-z\-]+/i
# Pre-release version, denoted from patch version with a hyphen # Pre-release version, denoted from patch version with a hyphen
{tag, tag_err} =
System.cmd("git", ["describe", "--tags", "--abbrev=0"], stderr_to_stdout: true)
{describe, describe_err} = System.cmd("git", ["describe", "--tags", "--abbrev=8"])
{commit_hash, commit_hash_err} = System.cmd("git", ["rev-parse", "--short", "HEAD"])
git_pre_release = git_pre_release =
with {tag, 0} <- cond do
System.cmd("git", ["describe", "--tags", "--abbrev=0"], stderr_to_stdout: true), tag_err == 0 and describe_err == 0 ->
{describe, 0} <- System.cmd("git", ["describe", "--tags", "--abbrev=8"]) do
describe describe
|> String.trim() |> String.trim()
|> String.replace(String.trim(tag), "") |> String.replace(String.trim(tag), "")
|> String.trim_leading("-") |> String.trim_leading("-")
|> String.trim() |> String.trim()
else
_ -> commit_hash_err == 0 ->
{commit_hash, 0} = System.cmd("git", ["rev-parse", "--short", "HEAD"])
"0-g" <> String.trim(commit_hash) "0-g" <> String.trim(commit_hash)
true ->
""
end end
# Branch name as pre-release version component, denoted with a dot # Branch name as pre-release version component, denoted with a dot
@ -251,6 +258,8 @@ defp version(version) do
|> String.replace(identifier_filter, "-") |> String.replace(identifier_filter, "-")
branch_name branch_name
else
_ -> "stable"
end end
build_name = build_name =

View file

@ -8,11 +8,13 @@ defmodule Pleroma.NotificationTest do
import Pleroma.Factory import Pleroma.Factory
import Mock import Mock
alias Pleroma.FollowingRelationship
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Tests.ObanHelpers alias Pleroma.Tests.ObanHelpers
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.NotificationView
alias Pleroma.Web.Push alias Pleroma.Web.Push
alias Pleroma.Web.Streamer alias Pleroma.Web.Streamer
@ -272,16 +274,6 @@ test "it doesn't create a notification for user if he is the activity author" do
refute Notification.create_notification(activity, author) refute Notification.create_notification(activity, author)
end end
test "it doesn't create a notification for follow-unfollow-follow chains" do
user = insert(:user)
followed_user = insert(:user)
{:ok, _, _, activity} = CommonAPI.follow(user, followed_user)
Notification.create_notification(activity, followed_user)
CommonAPI.unfollow(user, followed_user)
{:ok, _, _, activity_dupe} = CommonAPI.follow(user, followed_user)
refute Notification.create_notification(activity_dupe, followed_user)
end
test "it doesn't create duplicate notifications for follow+subscribed users" do test "it doesn't create duplicate notifications for follow+subscribed users" do
user = insert(:user) user = insert(:user)
subscriber = insert(:user) subscriber = insert(:user)
@ -304,6 +296,74 @@ test "it doesn't create subscription notifications if the recipient cannot see t
end end
end end
describe "follow / follow_request notifications" do
test "it creates `follow` notification for approved Follow activity" do
user = insert(:user)
followed_user = insert(:user, locked: false)
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
assert FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
assert %{type: "follow"} =
NotificationView.render("show.json", %{
notification: notification,
for: followed_user
})
end
test "if `follow_request` notifications are enabled, " <>
"it creates `follow_request` notification for pending Follow activity" do
clear_config([:notifications, :enable_follow_request_notifications], true)
user = insert(:user)
followed_user = insert(:user, locked: true)
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
refute FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
render_opts = %{notification: notification, for: followed_user}
assert %{type: "follow_request"} = NotificationView.render("show.json", render_opts)
# After request is accepted, the same notification is rendered with type "follow":
assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
notification_id = notification.id
assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
assert %{type: "follow"} = NotificationView.render("show.json", render_opts)
end
test "if `follow_request` notifications are disabled, " <>
"it does NOT create `follow*` notification for pending Follow activity" do
clear_config([:notifications, :enable_follow_request_notifications], false)
user = insert(:user)
followed_user = insert(:user, locked: true)
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
refute FollowingRelationship.following?(user, followed_user)
assert [] = Notification.for_user(followed_user)
# After request is accepted, no new notifications are generated:
assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
assert [] = Notification.for_user(followed_user)
end
test "it doesn't create a notification for follow-unfollow-follow chains" do
user = insert(:user)
followed_user = insert(:user, locked: false)
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
assert FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
CommonAPI.unfollow(user, followed_user)
{:ok, _, _, _activity_dupe} = CommonAPI.follow(user, followed_user)
notification_id = notification.id
assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
end
end
describe "get notification" do describe "get notification" do
test "it gets a notification that belongs to the user" do test "it gets a notification that belongs to the user" do
user = insert(:user) user = insert(:user)

View file

@ -20,26 +20,38 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
:ok :ok
end end
defp get_old_message do
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
end
defp get_new_message do
old_message = get_old_message()
new_object =
old_message
|> Map.get("object")
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
old_message
|> Map.put("object", new_object)
end
describe "with reject action" do describe "with reject action" do
test "it rejects an old post" do test "it rejects an old post" do
Config.put([:mrf_object_age, :actions], [:reject]) Config.put([:mrf_object_age, :actions], [:reject])
data = data = get_old_message()
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
{:reject, _} = ObjectAgePolicy.filter(data) assert match?({:reject, _}, ObjectAgePolicy.filter(data))
end end
test "it allows a new post" do test "it allows a new post" do
Config.put([:mrf_object_age, :actions], [:reject]) Config.put([:mrf_object_age, :actions], [:reject])
data = data = get_new_message()
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
{:ok, _} = ObjectAgePolicy.filter(data) assert match?({:ok, _}, ObjectAgePolicy.filter(data))
end end
end end
@ -47,9 +59,7 @@ test "it allows a new post" do
test "it delists an old post" do test "it delists an old post" do
Config.put([:mrf_object_age, :actions], [:delist]) Config.put([:mrf_object_age, :actions], [:delist])
data = data = get_old_message()
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
@ -61,14 +71,11 @@ test "it delists an old post" do
test "it allows a new post" do test "it allows a new post" do
Config.put([:mrf_object_age, :actions], [:delist]) Config.put([:mrf_object_age, :actions], [:delist])
data = data = get_new_message()
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
{:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"]) {:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"])
{:ok, ^data} = ObjectAgePolicy.filter(data) assert match?({:ok, ^data}, ObjectAgePolicy.filter(data))
end end
end end
@ -76,9 +83,7 @@ test "it allows a new post" do
test "it strips followers collections from an old post" do test "it strips followers collections from an old post" do
Config.put([:mrf_object_age, :actions], [:strip_followers]) Config.put([:mrf_object_age, :actions], [:strip_followers])
data = data = get_old_message()
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
{:ok, user} = User.get_or_fetch_by_ap_id(data["actor"]) {:ok, user} = User.get_or_fetch_by_ap_id(data["actor"])
@ -91,14 +96,11 @@ test "it strips followers collections from an old post" do
test "it allows a new post" do test "it allows a new post" do
Config.put([:mrf_object_age, :actions], [:strip_followers]) Config.put([:mrf_object_age, :actions], [:strip_followers])
data = data = get_new_message()
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
{:ok, ^data} = ObjectAgePolicy.filter(data) assert match?({:ok, ^data}, ObjectAgePolicy.filter(data))
end end
end end
end end

View file

@ -17,7 +17,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
reject: [], reject: [],
accept: [], accept: [],
avatar_removal: [], avatar_removal: [],
banner_removal: [] banner_removal: [],
reject_deletes: []
) )
describe "when :media_removal" do describe "when :media_removal" do
@ -382,6 +383,66 @@ test "match with wildcard domain" do
end end
end end
describe "when :reject_deletes is empty" do
setup do: Config.put([:mrf_simple, :reject_deletes], [])
test "it accepts deletions even from rejected servers" do
Config.put([:mrf_simple, :reject], ["remote.instance"])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
test "it accepts deletions even from non-whitelisted servers" do
Config.put([:mrf_simple, :accept], ["non.matching.remote"])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
end
describe "when :reject_deletes is not empty but it doesn't have a matching host" do
setup do: Config.put([:mrf_simple, :reject_deletes], ["non.matching.remote"])
test "it accepts deletions even from rejected servers" do
Config.put([:mrf_simple, :reject], ["remote.instance"])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
test "it accepts deletions even from non-whitelisted servers" do
Config.put([:mrf_simple, :accept], ["non.matching.remote"])
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
end
end
describe "when :reject_deletes has a matching host" do
setup do: Config.put([:mrf_simple, :reject_deletes], ["remote.instance"])
test "it rejects the deletion" do
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
end
end
describe "when :reject_deletes match with wildcard domain" do
setup do: Config.put([:mrf_simple, :reject_deletes], ["*.remote.instance"])
test "it rejects the deletion" do
deletion_message = build_remote_deletion_message()
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
end
end
defp build_local_message do defp build_local_message do
%{ %{
"actor" => "#{Pleroma.Web.base_url()}/users/alice", "actor" => "#{Pleroma.Web.base_url()}/users/alice",
@ -408,4 +469,11 @@ defp build_remote_user do
"type" => "Person" "type" => "Person"
} }
end end
defp build_remote_deletion_message do
%{
"type" => "Delete",
"actor" => "https://remote.instance/users/bob"
}
end
end end

View file

@ -35,7 +35,10 @@ defmacro assert_error_when_disable_push(do: yield) do
quote do quote do
vapid_details = Application.get_env(:web_push_encryption, :vapid_details, []) vapid_details = Application.get_env(:web_push_encryption, :vapid_details, [])
Application.put_env(:web_push_encryption, :vapid_details, []) Application.put_env(:web_push_encryption, :vapid_details, [])
assert "Something went wrong" == unquote(yield)
assert %{"error" => "Web push subscription is disabled on this Pleroma instance"} ==
unquote(yield)
Application.put_env(:web_push_encryption, :vapid_details, vapid_details) Application.put_env(:web_push_encryption, :vapid_details, vapid_details)
end end
end end
@ -45,7 +48,7 @@ test "returns error when push disabled ", %{conn: conn} do
assert_error_when_disable_push do assert_error_when_disable_push do
conn conn
|> post("/api/v1/push/subscription", %{}) |> post("/api/v1/push/subscription", %{})
|> json_response(500) |> json_response(403)
end end
end end
@ -74,7 +77,7 @@ test "returns error when push disabled ", %{conn: conn} do
assert_error_when_disable_push do assert_error_when_disable_push do
conn conn
|> get("/api/v1/push/subscription", %{}) |> get("/api/v1/push/subscription", %{})
|> json_response(500) |> json_response(403)
end end
end end
@ -127,7 +130,7 @@ test "returns error when push disabled ", %{conn: conn} do
assert_error_when_disable_push do assert_error_when_disable_push do
conn conn
|> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}}) |> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}})
|> json_response(500) |> json_response(403)
end end
end end
@ -155,7 +158,7 @@ test "returns error when push disabled ", %{conn: conn} do
assert_error_when_disable_push do assert_error_when_disable_push do
conn conn
|> delete("/api/v1/push/subscription", %{}) |> delete("/api/v1/push/subscription", %{})
|> json_response(500) |> json_response(403)
end end
end end

View file

@ -2,10 +2,10 @@
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do defmodule Pleroma.Web.MastodonAPI.SubscriptionViewTest do
use Pleroma.DataCase use Pleroma.DataCase
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View alias Pleroma.Web.MastodonAPI.SubscriptionView, as: View
alias Pleroma.Web.Push alias Pleroma.Web.Push
test "Represent a subscription" do test "Represent a subscription" do
@ -18,6 +18,6 @@ test "Represent a subscription" do
server_key: Keyword.get(Push.vapid_config(), :public_key) server_key: Keyword.get(Push.vapid_config(), :public_key)
} }
assert expected == View.render("push_subscription.json", %{subscription: subscription}) assert expected == View.render("show.json", %{subscription: subscription})
end end
end end