Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into emr_develop
This commit is contained in:
commit
44287702ad
|
@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
- **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
|
||||
- **Breaking**: Changed `mix pleroma.user toggle_activated` to `mix pleroma.user activate/deactivate`
|
||||
- **Breaking:** NSFW hashtag is no longer added on sensitive posts
|
||||
- Polls now always return a `voters_count`, even if they are single-choice.
|
||||
- Admin Emails: The ap id is used as the user link in emails now.
|
||||
- Improved registration workflow for email confirmation and account approval modes.
|
||||
|
@ -506,7 +507,6 @@ switched to a new configuration mechanism, however it was not officially removed
|
|||
- Static-FE: Fix remote posts not being sanitized
|
||||
|
||||
### Fixed
|
||||
=======
|
||||
- Rate limiter crashes when there is no explicitly specified ip in the config
|
||||
- 500 errors when no `Accept` header is present if Static-FE is enabled
|
||||
- Instance panel not being updated immediately due to wrong `Cache-Control` headers
|
||||
|
|
|
@ -391,6 +391,11 @@ config :pleroma, :mrf_keyword,
|
|||
federated_timeline_removal: [],
|
||||
replace: []
|
||||
|
||||
config :pleroma, :mrf_hashtag,
|
||||
sensitive: ["nsfw"],
|
||||
reject: [],
|
||||
federated_timeline_removal: []
|
||||
|
||||
config :pleroma, :mrf_subchain, match_actor: %{}
|
||||
|
||||
config :pleroma, :mrf_activity_expiration, days: 365
|
||||
|
|
|
@ -210,6 +210,16 @@ config :pleroma, :mrf_user_allowlist, %{
|
|||
|
||||
* `days`: Default global expiration time for all local Create activities (in days)
|
||||
|
||||
#### :mrf_hashtag
|
||||
|
||||
* `sensitive`: List of hashtags to mark activities as sensitive (default: `nsfw`)
|
||||
* `federated_timeline_removal`: List of hashtags to remove activities from the federated timeline (aka TWNK)
|
||||
* `reject`: List of hashtags to reject activities from
|
||||
|
||||
Notes:
|
||||
- The hashtags in the configuration do not have a leading `#`.
|
||||
- This MRF Policy is always enabled, if you want to disable it you have to set empty lists
|
||||
|
||||
### :activitypub
|
||||
* `unfollow_blocked`: Whether blocks result in people getting unfollowed
|
||||
* `outgoing_blocks`: Whether to federate blocks to other instances
|
||||
|
|
|
@ -1383,21 +1383,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
defp get_actor_url(_url), do: nil
|
||||
|
||||
defp normalize_image(%{"url" => url}) do
|
||||
%{
|
||||
"type" => "Image",
|
||||
"url" => [%{"href" => url}]
|
||||
}
|
||||
end
|
||||
|
||||
defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image()
|
||||
defp normalize_image(_), do: nil
|
||||
|
||||
defp object_to_user_data(data) do
|
||||
avatar =
|
||||
data["icon"]["url"] &&
|
||||
%{
|
||||
"type" => "Image",
|
||||
"url" => [%{"href" => data["icon"]["url"]}]
|
||||
}
|
||||
|
||||
banner =
|
||||
data["image"]["url"] &&
|
||||
%{
|
||||
"type" => "Image",
|
||||
"url" => [%{"href" => data["image"]["url"]}]
|
||||
}
|
||||
|
||||
fields =
|
||||
data
|
||||
|> Map.get("attachment", [])
|
||||
|
@ -1441,13 +1437,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
ap_id: data["id"],
|
||||
uri: get_actor_url(data["url"]),
|
||||
ap_enabled: true,
|
||||
banner: banner,
|
||||
banner: normalize_image(data["image"]),
|
||||
fields: fields,
|
||||
emoji: emojis,
|
||||
is_locked: is_locked,
|
||||
is_discoverable: is_discoverable,
|
||||
invisible: invisible,
|
||||
avatar: avatar,
|
||||
avatar: normalize_image(data["icon"]),
|
||||
name: data["name"],
|
||||
follower_address: data["followers"],
|
||||
following_address: data["following"],
|
||||
|
|
|
@ -92,7 +92,9 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
|||
end
|
||||
|
||||
def get_policies do
|
||||
Pleroma.Config.get([:mrf, :policies], []) |> get_policies()
|
||||
Pleroma.Config.get([:mrf, :policies], [])
|
||||
|> get_policies()
|
||||
|> Enum.concat([Pleroma.Web.ActivityPub.MRF.HashtagPolicy])
|
||||
end
|
||||
|
||||
defp get_policies(policy) when is_atom(policy), do: [policy]
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Object
|
||||
|
||||
@moduledoc """
|
||||
Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)
|
||||
|
||||
Note: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.
|
||||
"""
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||
|
||||
defp check_reject(message, hashtags) do
|
||||
if Enum.any?(Config.get([:mrf_hashtag, :reject]), fn match -> match in hashtags end) do
|
||||
{:reject, "[HashtagPolicy] Matches with rejected keyword"}
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_ftl_removal(%{"to" => to} = message, hashtags) do
|
||||
if Pleroma.Constants.as_public() in to and
|
||||
Enum.any?(Config.get([:mrf_hashtag, :federated_timeline_removal]), fn match ->
|
||||
match in hashtags
|
||||
end) do
|
||||
to = List.delete(to, Pleroma.Constants.as_public())
|
||||
cc = [Pleroma.Constants.as_public() | message["cc"] || []]
|
||||
|
||||
message =
|
||||
message
|
||||
|> Map.put("to", to)
|
||||
|> Map.put("cc", cc)
|
||||
|> Kernel.put_in(["object", "to"], to)
|
||||
|> Kernel.put_in(["object", "cc"], cc)
|
||||
|
||||
{:ok, message}
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_ftl_removal(message, _hashtags), do: {:ok, message}
|
||||
|
||||
defp check_sensitive(message, hashtags) do
|
||||
if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do
|
||||
{:ok, Kernel.put_in(message, ["object", "sensitive"], true)}
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Create", "object" => object} = message) do
|
||||
hashtags = Object.hashtags(%Object{data: object})
|
||||
|
||||
if hashtags != [] do
|
||||
with {:ok, message} <- check_reject(message, hashtags),
|
||||
{:ok, message} <- check_ftl_removal(message, hashtags),
|
||||
{:ok, message} <- check_sensitive(message, hashtags) do
|
||||
{:ok, message}
|
||||
end
|
||||
else
|
||||
{:ok, message}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(message), do: {:ok, message}
|
||||
|
||||
@impl true
|
||||
def describe do
|
||||
mrf_hashtag =
|
||||
Config.get(:mrf_hashtag)
|
||||
|> Enum.into(%{})
|
||||
|
||||
{:ok, %{mrf_hashtag: mrf_hashtag}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def config_description do
|
||||
%{
|
||||
key: :mrf_hashtag,
|
||||
related_policy: "Pleroma.Web.ActivityPub.MRF.HashtagPolicy",
|
||||
label: "MRF Hashtag",
|
||||
description: @moduledoc,
|
||||
children: [
|
||||
%{
|
||||
key: :reject,
|
||||
type: {:list, :string},
|
||||
description: "A list of hashtags which result in message being rejected.",
|
||||
suggestions: ["foo"]
|
||||
},
|
||||
%{
|
||||
key: :federated_timeline_removal,
|
||||
type: {:list, :string},
|
||||
description:
|
||||
"A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted).",
|
||||
suggestions: ["foo"]
|
||||
},
|
||||
%{
|
||||
key: :sensitive,
|
||||
type: {:list, :string},
|
||||
description:
|
||||
"A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)",
|
||||
suggestions: ["nsfw", "r18"]
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
|
@ -64,22 +64,16 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
|
|||
%{host: actor_host} = _actor_info,
|
||||
%{
|
||||
"type" => "Create",
|
||||
"object" => child_object
|
||||
"object" => %{} = _child_object
|
||||
} = object
|
||||
)
|
||||
when is_map(child_object) do
|
||||
) do
|
||||
media_nsfw =
|
||||
Config.get([:mrf_simple, :media_nsfw])
|
||||
|> MRF.subdomains_regex()
|
||||
|
||||
object =
|
||||
if MRF.subdomain_match?(media_nsfw, actor_host) do
|
||||
child_object =
|
||||
child_object
|
||||
|> Map.put("tag", (child_object["tag"] || []) ++ ["nsfw"])
|
||||
|> Map.put("sensitive", true)
|
||||
|
||||
Map.put(object, "object", child_object)
|
||||
Kernel.put_in(object, ["object", "sensitive"], true)
|
||||
else
|
||||
object
|
||||
end
|
||||
|
|
|
@ -28,20 +28,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
|
|||
"mrf_tag:media-force-nsfw",
|
||||
%{
|
||||
"type" => "Create",
|
||||
"object" => %{"attachment" => child_attachment} = object
|
||||
"object" => %{"attachment" => child_attachment}
|
||||
} = message
|
||||
)
|
||||
when length(child_attachment) > 0 do
|
||||
tags = (object["tag"] || []) ++ ["nsfw"]
|
||||
|
||||
object =
|
||||
object
|
||||
|> Map.put("tag", tags)
|
||||
|> Map.put("sensitive", true)
|
||||
|
||||
message = Map.put(message, "object", object)
|
||||
|
||||
{:ok, message}
|
||||
{:ok, Kernel.put_in(message, ["object", "sensitive"], true)}
|
||||
end
|
||||
|
||||
defp process_tag(
|
||||
|
|
|
@ -40,7 +40,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
|> fix_in_reply_to(options)
|
||||
|> fix_emoji()
|
||||
|> fix_tag()
|
||||
|> set_sensitive()
|
||||
|> fix_content_map()
|
||||
|> fix_addressing()
|
||||
|> fix_summary()
|
||||
|
@ -741,7 +740,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
# Prepares the object of an outgoing create activity.
|
||||
def prepare_object(object) do
|
||||
object
|
||||
|> set_sensitive
|
||||
|> add_hashtags
|
||||
|> add_mention_tags
|
||||
|> add_emoji_tags
|
||||
|
@ -932,15 +930,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
Map.put(object, "conversation", object["context"])
|
||||
end
|
||||
|
||||
def set_sensitive(%{"sensitive" => _} = object) do
|
||||
object
|
||||
end
|
||||
|
||||
def set_sensitive(object) do
|
||||
tags = object["tag"] || []
|
||||
Map.put(object, "sensitive", "nsfw" in tags)
|
||||
end
|
||||
|
||||
def set_type(%{"type" => "Answer"} = object) do
|
||||
Map.put(object, "type", "Note")
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
|
|||
|
||||
@behaviour Plug
|
||||
|
||||
alias OpenApiSpex.Plug.PutApiSpec
|
||||
alias Plug.Conn
|
||||
|
||||
@impl Plug
|
||||
|
@ -25,12 +26,10 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
|
|||
end
|
||||
|
||||
@impl Plug
|
||||
def call(%{private: %{open_api_spex: private_data}} = conn, %{
|
||||
operation_id: operation_id,
|
||||
render_error: render_error
|
||||
}) do
|
||||
spec = private_data.spec
|
||||
operation = private_data.operation_lookup[operation_id]
|
||||
|
||||
def call(conn, %{operation_id: operation_id, render_error: render_error}) do
|
||||
{spec, operation_lookup} = PutApiSpec.get_spec_and_operation_lookup(conn)
|
||||
operation = operation_lookup[operation_id]
|
||||
|
||||
content_type =
|
||||
case Conn.get_req_header(conn, "content-type") do
|
||||
|
@ -43,8 +42,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
|
|||
"application/json"
|
||||
end
|
||||
|
||||
private_data = Map.put(private_data, :operation_id, operation_id)
|
||||
conn = Conn.put_private(conn, :open_api_spex, private_data)
|
||||
conn = Conn.put_private(conn, :operation_id, operation_id)
|
||||
|
||||
case cast_and_validate(spec, operation, conn, content_type, strict?()) do
|
||||
{:ok, conn} ->
|
||||
|
@ -64,25 +62,22 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
|
|||
private: %{
|
||||
phoenix_controller: controller,
|
||||
phoenix_action: action,
|
||||
open_api_spex: private_data
|
||||
open_api_spex: %{spec_module: spec_module}
|
||||
}
|
||||
} = conn,
|
||||
opts
|
||||
) do
|
||||
{spec, operation_lookup} = PutApiSpec.get_spec_and_operation_lookup(conn)
|
||||
|
||||
operation =
|
||||
case private_data.operation_lookup[{controller, action}] do
|
||||
case operation_lookup[{controller, action}] do
|
||||
nil ->
|
||||
operation_id = controller.open_api_operation(action).operationId
|
||||
operation = private_data.operation_lookup[operation_id]
|
||||
operation = operation_lookup[operation_id]
|
||||
|
||||
operation_lookup =
|
||||
private_data.operation_lookup
|
||||
|> Map.put({controller, action}, operation)
|
||||
operation_lookup = Map.put(operation_lookup, {controller, action}, operation)
|
||||
|
||||
OpenApiSpex.Plug.Cache.adapter().put(
|
||||
private_data.spec_module,
|
||||
{private_data.spec, operation_lookup}
|
||||
)
|
||||
OpenApiSpex.Plug.Cache.adapter().put(spec_module, {spec, operation_lookup})
|
||||
|
||||
operation
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||
Operation.response(
|
||||
"Status. When `scheduled_at` is present, ScheduledStatus is returned instead",
|
||||
"application/json",
|
||||
%Schema{oneOf: [Status, ScheduledStatus]}
|
||||
%Schema{anyOf: [Status, ScheduledStatus]}
|
||||
),
|
||||
422 => Operation.response("Bad Request / MRF Rejection", "application/json", ApiError)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.Schemas.BooleanLike do
|
||||
alias OpenApiSpex.Cast
|
||||
alias OpenApiSpex.Schema
|
||||
|
||||
require OpenApiSpex
|
||||
|
@ -27,10 +28,13 @@ defmodule Pleroma.Web.ApiSpec.Schemas.BooleanLike do
|
|||
%Schema{type: :boolean},
|
||||
%Schema{type: :string},
|
||||
%Schema{type: :integer}
|
||||
]
|
||||
],
|
||||
"x-validate": __MODULE__
|
||||
})
|
||||
|
||||
def after_cast(value, _schmea) do
|
||||
{:ok, Pleroma.Web.ControllerHelper.truthy_param?(value)}
|
||||
def cast(%Cast{value: value} = context) do
|
||||
context
|
||||
|> Map.put(:value, Pleroma.Web.ControllerHelper.truthy_param?(value))
|
||||
|> Cast.ok()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -179,7 +179,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|
|||
end
|
||||
|
||||
defp sensitive(draft) do
|
||||
sensitive = draft.params[:sensitive] || Enum.member?(draft.tags, {"#nsfw", "nsfw"})
|
||||
sensitive = draft.params[:sensitive]
|
||||
%__MODULE__{draft | sensitive: sensitive}
|
||||
end
|
||||
|
||||
|
|
|
@ -217,7 +217,6 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
|||
draft.status
|
||||
|> format_input(content_type, options)
|
||||
|> maybe_add_attachments(draft.attachments, attachment_links)
|
||||
|> maybe_add_nsfw_tag(draft.params)
|
||||
end
|
||||
|
||||
defp get_content_type(content_type) do
|
||||
|
@ -228,13 +227,6 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
|||
end
|
||||
end
|
||||
|
||||
defp maybe_add_nsfw_tag({text, mentions, tags}, %{"sensitive" => sensitive})
|
||||
when sensitive in [true, "True", "true", "1"] do
|
||||
{text, mentions, [{"#nsfw", "nsfw"} | tags]}
|
||||
end
|
||||
|
||||
defp maybe_add_nsfw_tag(data, _), do: data
|
||||
|
||||
def make_context(_, %Participation{} = participation) do
|
||||
Repo.preload(participation, :conversation).conversation.ap_id
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.InstanceController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(
|
||||
:skip_plug,
|
||||
|
|
|
@ -381,12 +381,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
|
||||
page_url = page_url_data |> to_string
|
||||
|
||||
image_url =
|
||||
image_url_data =
|
||||
if is_binary(rich_media["image"]) do
|
||||
URI.merge(page_url_data, URI.parse(rich_media["image"]))
|
||||
|> to_string
|
||||
URI.parse(rich_media["image"])
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
image_url = build_image_url(image_url_data, page_url_data)
|
||||
|
||||
%{
|
||||
type: "link",
|
||||
provider_name: page_url_data.host,
|
||||
|
@ -542,4 +545,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
do: %{name: name, website: url}
|
||||
|
||||
defp build_application(_), do: nil
|
||||
|
||||
# Workaround for Elixir issue #10771
|
||||
# Avoid applying URI.merge unless necessary
|
||||
# TODO: revert to always attempting URI.merge(image_url_data, page_url_data)
|
||||
# when Elixir 1.12 is the minimum supported version
|
||||
@spec build_image_url(struct() | nil, struct()) :: String.t() | nil
|
||||
defp build_image_url(
|
||||
%URI{scheme: image_scheme, host: image_host} = image_url_data,
|
||||
%URI{} = _page_url_data
|
||||
)
|
||||
when not is_nil(image_scheme) and not is_nil(image_host) do
|
||||
image_url_data |> to_string
|
||||
end
|
||||
|
||||
defp build_image_url(%URI{} = image_url_data, %URI{} = page_url_data) do
|
||||
URI.merge(page_url_data, image_url_data) |> to_string
|
||||
end
|
||||
|
||||
defp build_image_url(_, _), do: nil
|
||||
end
|
||||
|
|
|
@ -121,6 +121,11 @@ defmodule Pleroma.Web.MediaProxy do
|
|||
end
|
||||
end
|
||||
|
||||
def decode_url(encoded) do
|
||||
[_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
|
||||
decode_url(sig, base64)
|
||||
end
|
||||
|
||||
defp signed_url(url) do
|
||||
:crypto.hmac(:sha, Config.get([Web.Endpoint, :secret_key_base]), url)
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupController do
|
|||
|
||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||
plug(OAuthScopesPlug, %{scopes: ["read:accounts"]} when action in [:index, :create])
|
||||
plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaBackupOperation
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do
|
|||
%{scopes: ["read:chats"]} when action in [:messages, :index, :index2, :show]
|
||||
)
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ChatOperation
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ defmodule Pleroma.Web.PleromaAPI.UserImportController do
|
|||
plug(OAuthScopesPlug, %{scopes: ["follow", "write:blocks"]} when action == :blocks)
|
||||
plug(OAuthScopesPlug, %{scopes: ["follow", "write:mutes"]} when action == :mutes)
|
||||
|
||||
plug(OpenApiSpex.Plug.CastAndValidate)
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
defdelegate open_api_operation(action), to: ApiSpec.UserImportOperation
|
||||
|
||||
def follow(%{body_params: %{list: %Plug.Upload{path: path}}} = conn, _) do
|
||||
|
|
|
@ -94,52 +94,56 @@ defmodule Pleroma.Web.WebFinger do
|
|||
|> XmlBuilder.to_doc()
|
||||
end
|
||||
|
||||
defp webfinger_from_xml(doc) do
|
||||
subject = XML.string_from_xpath("//Subject", doc)
|
||||
defp webfinger_from_xml(body) do
|
||||
with {:ok, doc} <- XML.parse_document(body) do
|
||||
subject = XML.string_from_xpath("//Subject", doc)
|
||||
|
||||
subscribe_address =
|
||||
~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}
|
||||
|> XML.string_from_xpath(doc)
|
||||
subscribe_address =
|
||||
~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}
|
||||
|> XML.string_from_xpath(doc)
|
||||
|
||||
ap_id =
|
||||
~s{//Link[@rel="self" and @type="application/activity+json"]/@href}
|
||||
|> XML.string_from_xpath(doc)
|
||||
ap_id =
|
||||
~s{//Link[@rel="self" and @type="application/activity+json"]/@href}
|
||||
|> XML.string_from_xpath(doc)
|
||||
|
||||
data = %{
|
||||
"subject" => subject,
|
||||
"subscribe_address" => subscribe_address,
|
||||
"ap_id" => ap_id
|
||||
}
|
||||
data = %{
|
||||
"subject" => subject,
|
||||
"subscribe_address" => subscribe_address,
|
||||
"ap_id" => ap_id
|
||||
}
|
||||
|
||||
{:ok, data}
|
||||
{:ok, data}
|
||||
end
|
||||
end
|
||||
|
||||
defp webfinger_from_json(doc) do
|
||||
data =
|
||||
Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn link, data ->
|
||||
case {link["type"], link["rel"]} do
|
||||
{"application/activity+json", "self"} ->
|
||||
Map.put(data, "ap_id", link["href"])
|
||||
defp webfinger_from_json(body) do
|
||||
with {:ok, doc} <- Jason.decode(body) do
|
||||
data =
|
||||
Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn link, data ->
|
||||
case {link["type"], link["rel"]} do
|
||||
{"application/activity+json", "self"} ->
|
||||
Map.put(data, "ap_id", link["href"])
|
||||
|
||||
{"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", "self"} ->
|
||||
Map.put(data, "ap_id", link["href"])
|
||||
{"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", "self"} ->
|
||||
Map.put(data, "ap_id", link["href"])
|
||||
|
||||
{nil, "http://ostatus.org/schema/1.0/subscribe"} ->
|
||||
Map.put(data, "subscribe_address", link["template"])
|
||||
{nil, "http://ostatus.org/schema/1.0/subscribe"} ->
|
||||
Map.put(data, "subscribe_address", link["template"])
|
||||
|
||||
_ ->
|
||||
Logger.debug("Unhandled type: #{inspect(link["type"])}")
|
||||
data
|
||||
end
|
||||
end)
|
||||
_ ->
|
||||
Logger.debug("Unhandled type: #{inspect(link["type"])}")
|
||||
data
|
||||
end
|
||||
end)
|
||||
|
||||
{:ok, data}
|
||||
{:ok, data}
|
||||
end
|
||||
end
|
||||
|
||||
def get_template_from_xml(body) do
|
||||
xpath = "//Link[@rel='lrdd']/@template"
|
||||
|
||||
with doc when doc != :error <- XML.parse_document(body),
|
||||
with {:ok, doc} <- XML.parse_document(body),
|
||||
template when template != nil <- XML.string_from_xpath(xpath, doc) do
|
||||
{:ok, template}
|
||||
end
|
||||
|
@ -192,15 +196,23 @@ defmodule Pleroma.Web.WebFinger do
|
|||
address,
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
),
|
||||
{:ok, %{status: status, body: body}} when status in 200..299 <- response do
|
||||
doc = XML.parse_document(body)
|
||||
{:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <-
|
||||
response do
|
||||
case List.keyfind(headers, "content-type", 0) do
|
||||
{_, content_type} ->
|
||||
case Plug.Conn.Utils.media_type(content_type) do
|
||||
{:ok, "application", subtype, _} when subtype in ~w(xrd+xml xml) ->
|
||||
webfinger_from_xml(body)
|
||||
|
||||
if doc != :error do
|
||||
webfinger_from_xml(doc)
|
||||
else
|
||||
with {:ok, doc} <- Jason.decode(body) do
|
||||
webfinger_from_json(doc)
|
||||
end
|
||||
{:ok, "application", subtype, _} when subtype in ~w(jrd+json json) ->
|
||||
webfinger_from_json(body)
|
||||
|
||||
_ ->
|
||||
{:error, {:content_type, content_type}}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:error, {:content_type, nil}}
|
||||
end
|
||||
else
|
||||
e ->
|
||||
|
|
|
@ -31,7 +31,7 @@ defmodule Pleroma.Web.XML do
|
|||
|> :binary.bin_to_list()
|
||||
|> :xmerl_scan.string(quiet: true)
|
||||
|
||||
doc
|
||||
{:ok, doc}
|
||||
rescue
|
||||
_e ->
|
||||
Logger.debug("Couldn't parse XML: #{inspect(text)}")
|
||||
|
|
4
mix.exs
4
mix.exs
|
@ -198,9 +198,7 @@ defmodule Pleroma.Mixfile do
|
|||
{:majic,
|
||||
git: "https://git.pleroma.social/pleroma/elixir-libraries/majic.git",
|
||||
ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"},
|
||||
{:open_api_spex,
|
||||
git: "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git",
|
||||
ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"},
|
||||
{:open_api_spex, "~> 3.10"},
|
||||
|
||||
## dev & test
|
||||
{:ex_doc, "~> 0.22", only: :dev, runtime: false},
|
||||
|
|
8
mix.lock
8
mix.lock
|
@ -52,7 +52,7 @@
|
|||
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
|
||||
"gen_stage": {:hex, :gen_stage, "0.14.3", "d0c66f1c87faa301c1a85a809a3ee9097a4264b2edf7644bf5c123237ef732bf", [:mix], [], "hexpm"},
|
||||
"gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"},
|
||||
"gettext": {:hex, :gettext, "0.18.0", "406d6b9e0e3278162c2ae1de0a60270452c553536772167e2d701f028116f870", [:mix], [], "hexpm", "c3f850be6367ebe1a08616c2158affe4a23231c70391050bf359d5f92f66a571"},
|
||||
"gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
|
||||
"gun": {:git, "https://github.com/ninenines/gun.git", "921c47146b2d9567eac7e9a4d2ccc60fffd4f327", [ref: "921c47146b2d9567eac7e9a4d2ccc60fffd4f327"]},
|
||||
"hackney": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/hackney.git", "7d7119f0651515d6d7669c78393fd90950a3ec6e", [ref: "7d7119f0651515d6d7669c78393fd90950a3ec6e"]},
|
||||
"html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"},
|
||||
|
@ -83,7 +83,7 @@
|
|||
"nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"},
|
||||
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
|
||||
"oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"},
|
||||
"open_api_spex": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git", "f296ac0924ba3cf79c7a588c4c252889df4c2edd", [ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"]},
|
||||
"open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.18", "3fe224de5b2e190d730a3c5da9d6e8540c96484cf4b4692921d1e28f0c32b01c", [:rebar3], [], "hexpm", "1fc8773a71a15553b179c986b22fbeead19b28fe486c332d4929700ffeb71f88"},
|
||||
"parse_trans": {:git, "https://github.com/uwiger/parse_trans.git", "76abb347c3c1d00fb0ccf9e4b43e22b3d2288484", [tag: "3.3.0"]},
|
||||
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},
|
||||
|
@ -117,9 +117,9 @@
|
|||
"syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"},
|
||||
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
|
||||
"tesla": {:hex, :tesla, "1.4.0", "1081bef0124b8bdec1c3d330bbe91956648fb008cf0d3950a369cda466a31a87", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "bf1374a5569f5fca8e641363b63f7347d680d91388880979a33bc12a6eb3e0aa"},
|
||||
"timex": {:hex, :timex, "3.6.2", "845cdeb6119e2fef10751c0b247b6c59d86d78554c83f78db612e3290f819bc2", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "26030b46199d02a590be61c2394b37ea25a3664c02fafbeca0b24c972025d47a"},
|
||||
"timex": {:hex, :timex, "3.7.3", "df8a2ea814749d700d6878ab9eacac9fdb498ecee2f507cb0002ec172bc24d0f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8691c1d86ca3a7bc14a156e2199dc8927be95d1a8f0e3b69e4bb2d6262c53ac6"},
|
||||
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
|
||||
"tzdata": {:hex, :tzdata, "1.0.4", "a3baa4709ea8dba552dca165af6ae97c624a2d6ac14bd265165eaa8e8af94af6", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "b02637db3df1fd66dd2d3c4f194a81633d0e4b44308d36c1b2fdfd1e4e6f169b"},
|
||||
"tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"},
|
||||
"ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"},
|
||||
"unicode_util_compat": {:git, "https://github.com/benoitc/unicode_util_compat.git", "38d7bc105f51159e8ea3279c40121db9db1e652f", [tag: "0.3.1"]},
|
||||
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
{
|
||||
"id": "https://fed.brid.gy/jk.nipponalba.scot",
|
||||
"url": "https://fed.brid.gy/r/https://jk.nipponalba.scot",
|
||||
"urls": [
|
||||
{
|
||||
"value": "https://jk.nipponalba.scot"
|
||||
},
|
||||
{
|
||||
"value": "https://social.nipponalba.scot/jk"
|
||||
},
|
||||
{
|
||||
"value": "https://px.nipponalba.scot/jk"
|
||||
}
|
||||
],
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"type": "Person",
|
||||
"name": "J K 🇯🇵🏴",
|
||||
"image": [
|
||||
{
|
||||
"url": "https://jk.nipponalba.scot/images/profile.jpg",
|
||||
"type": "Image",
|
||||
"name": "profile picture"
|
||||
}
|
||||
],
|
||||
"tag": [
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Craft Beer"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Single Malt Whisky"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Homebrewing"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Scottish Politics"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Scottish History"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Japanese History"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Tech"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Veganism"
|
||||
},
|
||||
{
|
||||
"type": "Tag",
|
||||
"name": "Cooking"
|
||||
}
|
||||
],
|
||||
"icon": [
|
||||
{
|
||||
"url": "https://jk.nipponalba.scot/images/profile.jpg",
|
||||
"type": "Image",
|
||||
"name": "profile picture"
|
||||
}
|
||||
],
|
||||
"preferredUsername": "jk.nipponalba.scot",
|
||||
"summary": "",
|
||||
"publicKey": {
|
||||
"id": "jk.nipponalba.scot",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdarxwzxnNbJ2hneWOYHkYJowk\npyigQtxlUd0VjgSQHwxU9kWqfbrHBVADyTtcqi/4dAzQd3UnCI1TPNnn4LPZY9PW\noiWd3Zl1/EfLFxO7LU9GS7fcSLQkyj5JNhSlN3I8QPudZbybrgRDVZYooDe1D+52\n5KLGqC2ajrIVOiDRTQIDAQAB\n-----END PUBLIC KEY-----"
|
||||
},
|
||||
"inbox": "https://fed.brid.gy/jk.nipponalba.scot/inbox",
|
||||
"outbox": "https://fed.brid.gy/jk.nipponalba.scot/outbox",
|
||||
"following": "https://fed.brid.gy/jk.nipponalba.scot/following",
|
||||
"followers": "https://fed.brid.gy/jk.nipponalba.scot/followers"
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||
<Link rel="lrdd" template="https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource={uri}" type="application/xrd+xml" />
|
||||
</XRD>
|
|
@ -208,6 +208,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert user.name == "Bernie2020 group"
|
||||
assert user.actor_type == "Group"
|
||||
end
|
||||
|
||||
test "works for bridgy actors" do
|
||||
user_id = "https://fed.brid.gy/jk.nipponalba.scot"
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: :get, url: ^user_id} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/bridgy/actor.json"),
|
||||
headers: [{"content-type", "application/activity+json"}]
|
||||
}
|
||||
end)
|
||||
|
||||
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
||||
|
||||
assert user.actor_type == "Person"
|
||||
|
||||
assert user.avatar == %{
|
||||
"type" => "Image",
|
||||
"url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}]
|
||||
}
|
||||
|
||||
assert user.banner == %{
|
||||
"type" => "Image",
|
||||
"url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
test "it fetches the appropriate tag-restricted posts" do
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicyTest do
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "it sets the sensitive property with relevant hashtags" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#nsfw hey"})
|
||||
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
assert modified["object"]["sensitive"]
|
||||
end
|
||||
|
||||
test "it doesn't sets the sensitive property with irrelevant hashtags" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe hey"})
|
||||
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
refute modified["object"]["sensitive"]
|
||||
end
|
||||
end
|
|
@ -75,10 +75,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
local_message = build_local_message()
|
||||
|
||||
assert SimplePolicy.filter(media_message) ==
|
||||
{:ok,
|
||||
media_message
|
||||
|> put_in(["object", "tag"], ["foo", "nsfw"])
|
||||
|> put_in(["object", "sensitive"], true)}
|
||||
{:ok, put_in(media_message, ["object", "sensitive"], true)}
|
||||
|
||||
assert SimplePolicy.filter(local_message) == {:ok, local_message}
|
||||
end
|
||||
|
@ -89,10 +86,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
local_message = build_local_message()
|
||||
|
||||
assert SimplePolicy.filter(media_message) ==
|
||||
{:ok,
|
||||
media_message
|
||||
|> put_in(["object", "tag"], ["foo", "nsfw"])
|
||||
|> put_in(["object", "sensitive"], true)}
|
||||
{:ok, put_in(media_message, ["object", "sensitive"], true)}
|
||||
|
||||
assert SimplePolicy.filter(local_message) == {:ok, local_message}
|
||||
end
|
||||
|
|
|
@ -114,7 +114,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do
|
|||
except_message = %{
|
||||
"actor" => actor.ap_id,
|
||||
"type" => "Create",
|
||||
"object" => %{"tag" => ["test", "nsfw"], "attachment" => ["file1"], "sensitive" => true}
|
||||
"object" => %{"tag" => ["test"], "attachment" => ["file1"], "sensitive" => true}
|
||||
}
|
||||
|
||||
assert TagPolicy.filter(message) == {:ok, except_message}
|
||||
|
|
|
@ -68,7 +68,12 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
|
|||
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.NoOpPolicy])
|
||||
|
||||
expected = %{
|
||||
mrf_policies: ["NoOpPolicy"],
|
||||
mrf_policies: ["NoOpPolicy", "HashtagPolicy"],
|
||||
mrf_hashtag: %{
|
||||
federated_timeline_removal: [],
|
||||
reject: [],
|
||||
sensitive: ["nsfw"]
|
||||
},
|
||||
exclusions: false
|
||||
}
|
||||
|
||||
|
@ -79,8 +84,13 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
|
|||
clear_config([:mrf, :policies], [MRFModuleMock])
|
||||
|
||||
expected = %{
|
||||
mrf_policies: ["MRFModuleMock"],
|
||||
mrf_policies: ["MRFModuleMock", "HashtagPolicy"],
|
||||
mrf_module_mock: "some config data",
|
||||
mrf_hashtag: %{
|
||||
federated_timeline_removal: [],
|
||||
reject: [],
|
||||
sensitive: ["nsfw"]
|
||||
},
|
||||
exclusions: false
|
||||
}
|
||||
|
||||
|
|
|
@ -153,15 +153,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "it adds the sensitive property" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#nsfw hey"})
|
||||
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
assert modified["object"]["sensitive"]
|
||||
end
|
||||
|
||||
test "it adds the json-ld context and the conversation property" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
@ -11,8 +11,7 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
defp decode_result(encoded) do
|
||||
[_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
|
||||
{:ok, decoded} = MediaProxy.decode_url(sig, base64)
|
||||
{:ok, decoded} = MediaProxy.decode_url(encoded)
|
||||
decoded
|
||||
end
|
||||
|
||||
|
|
|
@ -45,6 +45,26 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||
assert {:error, _} = WebFinger.finger("pleroma.social")
|
||||
end
|
||||
|
||||
test "returns error when there is no content-type header" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{url: "http://social.heldscal.la/.well-known/host-meta"} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/social.heldscal.la_host_meta")
|
||||
}}
|
||||
|
||||
%{
|
||||
url:
|
||||
"https://social.heldscal.la/.well-known/webfinger?resource=acct:invalid_content@social.heldscal.la"
|
||||
} ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
user = "invalid_content@social.heldscal.la"
|
||||
assert {:error, {:content_type, nil}} = WebFinger.finger(user)
|
||||
end
|
||||
|
||||
test "returns error when fails parse xml or json" do
|
||||
user = "invalid_content@social.heldscal.la"
|
||||
assert {:error, %Jason.DecodeError{}} = WebFinger.finger(user)
|
||||
|
@ -113,5 +133,52 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||
ap_id = "https://" <> to_string(:idna.encode("zetsubou.みんな")) <> "/users/lain"
|
||||
{:ok, _data} = WebFinger.finger(ap_id)
|
||||
end
|
||||
|
||||
test "respects json content-type" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{
|
||||
url:
|
||||
"https://mastodon.social/.well-known/webfinger?resource=acct:emelie@mastodon.social"
|
||||
} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/webfinger_emelie.json"),
|
||||
headers: [{"content-type", "application/jrd+json"}]
|
||||
}}
|
||||
|
||||
%{url: "http://mastodon.social/.well-known/host-meta"} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/mastodon.social_host_meta")
|
||||
}}
|
||||
end)
|
||||
|
||||
{:ok, _data} = WebFinger.finger("emelie@mastodon.social")
|
||||
end
|
||||
|
||||
test "respects xml content-type" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{
|
||||
url: "https://pawoo.net/.well-known/webfinger?resource=acct:pekorino@pawoo.net"
|
||||
} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/https___pawoo.net_users_pekorino.xml"),
|
||||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
|
||||
%{url: "http://pawoo.net/.well-known/host-meta"} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta")
|
||||
}}
|
||||
end)
|
||||
|
||||
{:ok, _data} = WebFinger.finger("pekorino@pawoo.net")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -67,13 +67,11 @@ defmodule Pleroma.Web.ConnCase do
|
|||
end
|
||||
|
||||
defp json_response_and_validate_schema(
|
||||
%{
|
||||
private: %{
|
||||
open_api_spex: %{operation_id: op_id, operation_lookup: lookup, spec: spec}
|
||||
}
|
||||
} = conn,
|
||||
%{private: %{operation_id: op_id}} = conn,
|
||||
status
|
||||
) do
|
||||
{spec, lookup} = OpenApiSpex.Plug.PutApiSpec.get_spec_and_operation_lookup(conn)
|
||||
|
||||
content_type =
|
||||
conn
|
||||
|> Plug.Conn.get_resp_header("content-type")
|
||||
|
|
|
@ -122,7 +122,7 @@ defmodule HttpRequestMock do
|
|||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/mike@osada.macgirvin.com.json"),
|
||||
headers: activitypub_object_headers()
|
||||
headers: [{"content-type", "application/jrd+json"}]
|
||||
}}
|
||||
end
|
||||
|
||||
|
@ -187,7 +187,8 @@ defmodule HttpRequestMock do
|
|||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/lain_squeet.me_webfinger.xml")
|
||||
body: File.read!("test/fixtures/tesla_mock/lain_squeet.me_webfinger.xml"),
|
||||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
end
|
||||
|
||||
|
@ -526,22 +527,6 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("http://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/xn--q9jyb4c_host_meta")
|
||||
}}
|
||||
end
|
||||
|
||||
def get("https://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/xn--q9jyb4c_host_meta")
|
||||
}}
|
||||
end
|
||||
|
||||
def get("http://pleroma.soykaf.com/.well-known/host-meta", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
@ -786,7 +771,8 @@ defmodule HttpRequestMock do
|
|||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/shp@social.heldscal.la.xml")
|
||||
body: File.read!("test/fixtures/tesla_mock/shp@social.heldscal.la.xml"),
|
||||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
end
|
||||
|
||||
|
@ -796,7 +782,7 @@ defmodule HttpRequestMock do
|
|||
_,
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
{:ok, %Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/jrd+json"}]}}
|
||||
end
|
||||
|
||||
def get("http://framatube.org/.well-known/host-meta", _, _, _) do
|
||||
|
@ -816,7 +802,7 @@ defmodule HttpRequestMock do
|
|||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/json"}],
|
||||
headers: [{"content-type", "application/jrd+json"}],
|
||||
body: File.read!("test/fixtures/tesla_mock/framasoft@framatube.org.json")
|
||||
}}
|
||||
end
|
||||
|
@ -876,7 +862,7 @@ defmodule HttpRequestMock do
|
|||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/json"}],
|
||||
headers: [{"content-type", "application/jrd+json"}],
|
||||
body: File.read!("test/fixtures/tesla_mock/kaniini@gerzilla.de.json")
|
||||
}}
|
||||
end
|
||||
|
@ -1074,7 +1060,8 @@ defmodule HttpRequestMock do
|
|||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/lain.xml")
|
||||
body: File.read!("test/fixtures/lain.xml"),
|
||||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
end
|
||||
|
||||
|
@ -1087,7 +1074,16 @@ defmodule HttpRequestMock do
|
|||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/lain.xml")
|
||||
body: File.read!("test/fixtures/lain.xml"),
|
||||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
end
|
||||
|
||||
def get("http://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/host-meta-zetsubou.xn--q9jyb4c.xml")
|
||||
}}
|
||||
end
|
||||
|
||||
|
@ -1153,7 +1149,8 @@ defmodule HttpRequestMock do
|
|||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/kpherox@mstdn.jp.xml")
|
||||
body: File.read!("test/fixtures/tesla_mock/kpherox@mstdn.jp.xml"),
|
||||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue