Merge remote-tracking branch 'pleroma/develop' into merge-pleroma

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2023-03-15 19:39:24 +01:00
commit bda8589f16
55 changed files with 563 additions and 132 deletions

View file

@ -12,7 +12,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
- rel="me" was missing its cache
### Removed
- BREAKING: Support for passwords generated with `crypt(3)` (Gnu Social migration artifact)
## 2.5.1
### Added
- Allow customizing instance languages
### Fixed
- Security: uploading HTTP endpoint can no longer create directories in the upload dir (internal APIs, like backup, still can do it.)
- ~ character in urls in Markdown posts are handled properly
- Exiftool upload filter will now ignore SVG files
- Fix `block_from_stranger` setting
- Fix rel="me"
- Docker images will now run properly
- Fix inproper content being cached in report content
- Notification filter on object content will not operate on the ones that inherently have no content
- ZWNJ and double dots in links are parsed properly for Plain-text posts
- OTP releases will work on systems with a newer libcrypt
- Errors when running Exiftool.ReadDescription filter will not be filled into the image description
## 2.5.0 - 2022-12-23

View file

@ -1080,6 +1080,15 @@
description:
"Number of days for which users won't be able to migrate account again after successful migration.",
suggestions: [30]
},
%{
key: :languages,
type: {:list, :string},
description:
"Languages to be exposed in /api/v1/instance. Should be in the format of BCP47 language codes.",
suggestions: [
"en"
]
}
]
},

View file

@ -6,7 +6,70 @@ defmodule Mix.Tasks.Pleroma.OpenapiSpec do
def run([path]) do
# Load Pleroma application to get version info
Application.load(:pleroma)
spec = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
File.write(path, spec)
spec_json = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
# to get rid of the structs
spec_regened = spec_json |> Jason.decode!()
check_specs!(spec_regened)
File.write(path, spec_json)
end
defp check_specs!(spec) do
with :ok <- check_specs(spec) do
:ok
else
{_, errors} ->
IO.puts(IO.ANSI.format([:red, :bright, "Spec check failed, errors:"]))
Enum.map(errors, &IO.puts/1)
raise "Spec check failed"
end
end
def check_specs(spec) do
errors =
spec["paths"]
|> Enum.flat_map(fn {path, %{} = endpoints} ->
Enum.map(
endpoints,
fn {method, endpoint} ->
with :ok <- check_endpoint(spec, endpoint) do
:ok
else
error ->
"#{endpoint["operationId"]} (#{method} #{path}): #{error}"
end
end
)
|> Enum.reject(fn res -> res == :ok end)
end)
if errors == [] do
:ok
else
{:error, errors}
end
end
defp check_endpoint(spec, endpoint) do
valid_tags = available_tags(spec)
with {_, [_ | _] = tags} <- {:tags, endpoint["tags"]},
{_, []} <- {:unavailable, Enum.reject(tags, &(&1 in valid_tags))} do
:ok
else
{:tags, _} ->
"No tags specified"
{:unavailable, tags} ->
"Tags #{inspect(tags)} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
end
end
defp available_tags(spec) do
spec["x-tagGroups"]
|> Enum.flat_map(fn %{"tags" => tags} -> tags end)
end
end

View file

@ -183,6 +183,7 @@ defp exclude_filtered(query, user) do
from([_n, a, o] in query,
where:
fragment("not(?->>'content' ~* ?)", o.data, ^regex) or
fragment("?->>'content' is null", o.data) or
fragment("?->>'actor' = ?", o.data, ^user.ap_id)
)
end
@ -816,7 +817,7 @@ def skip?(
cond do
opts[:type] == "poll" -> false
user.ap_id == actor -> false
!User.following?(follower, user) -> true
!User.following?(user, follower) -> true
true -> false
end
end

View file

@ -33,7 +33,10 @@ defp read_when_empty(current_description, _, _) when is_binary(current_descripti
defp read_when_empty(_, file, tag) do
try do
{tag_content, 0} =
System.cmd("exiftool", ["-b", "-s3", tag, file], stderr_to_stdout: true, parallelism: true)
System.cmd("exiftool", ["-b", "-s3", tag, file],
stderr_to_stdout: false,
parallelism: true
)
tag_content = String.trim(tag_content)

View file

@ -42,7 +42,7 @@ def extract_report_info(
defp make_fake_activity(act, user) do
%Activity{
id: "pleroma:fake",
id: "pleroma:fake:#{act["id"]}",
data: %{
"actor" => user.ap_id,
"type" => "Create",

View file

@ -95,7 +95,8 @@ def spec(opts \\ []) do
"Relays",
"Report managment",
"Status administration",
"User administration"
"User administration",
"Announcement management"
]
},
%{"name" => "Applications", "tags" => ["Applications", "Push subscriptions"]},
@ -110,10 +111,12 @@ def spec(opts \\ []) do
"Follow requests",
"Mascot",
"Markers",
"Notifications"
"Notifications",
"Filters",
"Settings"
]
},
%{"name" => "Instance", "tags" => ["Custom emojis"]},
%{"name" => "Instance", "tags" => ["Custom emojis", "Instance misc"]},
%{"name" => "Messaging", "tags" => ["Chats", "Conversations"]},
%{
"name" => "Statuses",
@ -125,10 +128,21 @@ def spec(opts \\ []) do
"Retrieve status information",
"Scheduled statuses",
"Search",
"Status actions"
"Status actions",
"Media attachments"
]
},
%{"name" => "Miscellaneous", "tags" => ["Emoji packs", "Reports", "Suggestions"]}
%{
"name" => "Miscellaneous",
"tags" => [
"Emoji packs",
"Reports",
"Suggestions",
"Announcements",
"Remote interaction",
"Others"
]
}
]
}
}

View file

@ -458,7 +458,7 @@ def blocks_operation do
operationId: "AccountController.blocks",
description: "View your blocks. See also accounts/:id/{block,unblock}",
security: [%{"oAuth" => ["read:blocks"]}],
parameters: pagination_params(),
parameters: [with_relationships_param() | pagination_params()],
responses: %{
200 => Operation.response("Accounts", "application/json", array_of_accounts())
}
@ -467,7 +467,7 @@ def blocks_operation do
def lookup_operation do
%Operation{
tags: ["Account lookup"],
tags: ["Retrieve account information"],
summary: "Find a user by nickname",
operationId: "AccountController.lookup",
parameters: [

View file

@ -17,7 +17,7 @@ def open_api_operation(action) do
def index_operation do
%Operation{
tags: ["Announcement managment"],
tags: ["Announcement management"],
summary: "Retrieve a list of announcements",
operationId: "AdminAPI.AnnouncementController.index",
security: [%{"oAuth" => ["admin:read"]}],
@ -46,7 +46,7 @@ def index_operation do
def show_operation do
%Operation{
tags: ["Announcement managment"],
tags: ["Announcement management"],
summary: "Display one announcement",
operationId: "AdminAPI.AnnouncementController.show",
security: [%{"oAuth" => ["admin:read"]}],
@ -69,7 +69,7 @@ def show_operation do
def delete_operation do
%Operation{
tags: ["Announcement managment"],
tags: ["Announcement management"],
summary: "Delete one announcement",
operationId: "AdminAPI.AnnouncementController.delete",
security: [%{"oAuth" => ["admin:write"]}],
@ -92,7 +92,7 @@ def delete_operation do
def create_operation do
%Operation{
tags: ["Announcement managment"],
tags: ["Announcement management"],
summary: "Create one announcement",
operationId: "AdminAPI.AnnouncementController.create",
security: [%{"oAuth" => ["admin:write"]}],
@ -107,7 +107,7 @@ def create_operation do
def change_operation do
%Operation{
tags: ["Announcement managment"],
tags: ["Announcement management"],
summary: "Change one announcement",
operationId: "AdminAPI.AnnouncementController.change",
security: [%{"oAuth" => ["admin:write"]}],

View file

@ -70,7 +70,7 @@ def index_operation do
def show_operation do
%Operation{
tags: ["Status adminitration)"],
tags: ["Status administration"],
summary: "Get status",
operationId: "AdminAPI.StatusController.show",
parameters: [id_param() | admin_api_params()],
@ -84,7 +84,7 @@ def show_operation do
def update_operation do
%Operation{
tags: ["Status adminitration)"],
tags: ["Status administration"],
summary: "Change the scope of a status",
operationId: "AdminAPI.StatusController.update",
parameters: [id_param() | admin_api_params()],
@ -99,7 +99,7 @@ def update_operation do
def delete_operation do
%Operation{
tags: ["Status adminitration)"],
tags: ["Status administration"],
summary: "Delete status",
operationId: "AdminAPI.StatusController.delete",
parameters: [id_param() | admin_api_params()],
@ -143,7 +143,7 @@ def admin_account do
}
},
tags: %Schema{type: :string},
is_confirmed: %Schema{type: :string}
is_confirmed: %Schema{type: :boolean}
}
}
end

View file

@ -15,7 +15,7 @@ def open_api_operation(action) do
def index_operation do
%Operation{
tags: ["Announcement"],
tags: ["Announcements"],
summary: "Retrieve a list of announcements",
operationId: "MastodonAPI.AnnouncementController.index",
security: [%{"oAuth" => []}],
@ -28,7 +28,7 @@ def index_operation do
def mark_read_operation do
%Operation{
tags: ["Announcement"],
tags: ["Announcements"],
summary: "Mark one announcement as read",
operationId: "MastodonAPI.AnnouncementController.mark_read",
security: [%{"oAuth" => ["write:accounts"]}],

View file

@ -17,7 +17,7 @@ def open_api_operation(action) do
def index_operation do
%Operation{
tags: ["Directory"],
tags: ["Others"],
summary: "Profile directory",
operationId: "DirectoryController.index",
parameters:

View file

@ -13,7 +13,7 @@ def open_api_operation(action) do
def show_operation do
%Operation{
tags: ["Instance"],
tags: ["Instance misc"],
summary: "Retrieve instance information",
description: "Information about the server",
operationId: "InstanceController.show",
@ -37,7 +37,7 @@ def show2_operation do
def peers_operation do
%Operation{
tags: ["Instance"],
tags: ["Instance misc"],
summary: "Retrieve list of known instances",
operationId: "InstanceController.peers",
responses: %{

View file

@ -133,7 +133,11 @@ defp name_param do
defp files_object do
%Schema{
type: :object,
additionalProperties: %Schema{type: :string},
additionalProperties: %Schema{
type: :string,
description: "Filename of the emoji",
extensions: %{"x-additionalPropertiesName": "Emoji name"}
},
description: "Object with emoji names as keys and filenames as values"
}
end

View file

@ -227,13 +227,29 @@ defp ok_response do
defp emoji_packs_response do
Operation.response(
"Object with pack names as keys and pack contents as values",
"Emoji packs and the count",
"application/json",
%Schema{
type: :object,
additionalProperties: emoji_pack(),
properties: %{
packs: %Schema{
type: :object,
description: "Object with pack names as keys and pack contents as values",
additionalProperties: %Schema{
emoji_pack()
| extensions: %{"x-additionalPropertiesName": "Pack name"}
}
},
count: %Schema{
type: :integer,
description: "Number of emoji packs"
}
},
example: %{
"emojos" => emoji_pack().example
"packs" => %{
"emojos" => emoji_pack().example
},
"count" => 1
}
}
)
@ -274,7 +290,11 @@ defp emoji_pack do
defp files_object do
%Schema{
type: :object,
additionalProperties: %Schema{type: :string},
additionalProperties: %Schema{
type: :string,
description: "Filename",
extensions: %{"x-additionalPropertiesName": "Emoji name"}
},
description: "Object with emoji names as keys and filenames as values"
}
end

View file

@ -13,7 +13,7 @@ def open_api_operation(action) do
def show_operation do
%Operation{
tags: ["Instance"],
tags: ["Instance misc"],
summary: "Retrieve federation status",
description: "Information about instances deemed unreachable by the server",
operationId: "PleromaInstances.show",

View file

@ -473,7 +473,7 @@ def bookmarks_operation do
def show_history_operation do
%Operation{
tags: ["Retrieve status history"],
tags: ["Retrieve status information"],
summary: "Status history",
description: "View history of a status",
operationId: "StatusController.show_history",
@ -490,7 +490,7 @@ def show_history_operation do
def show_source_operation do
%Operation{
tags: ["Retrieve status source"],
tags: ["Retrieve status information"],
summary: "Status source",
description: "View source of a status",
operationId: "StatusController.show_source",
@ -507,7 +507,7 @@ def show_source_operation do
def update_operation do
%Operation{
tags: ["Update status"],
tags: ["Status actions"],
summary: "Update status",
description: "Change the content of a status",
operationId: "StatusController.update",

View file

@ -17,7 +17,7 @@ def open_api_operation(action) do
def emoji_operation do
%Operation{
tags: ["Emojis"],
tags: ["Custom emojis"],
summary: "List all custom emojis",
operationId: "UtilController.emoji",
parameters: [],
@ -30,7 +30,8 @@ def emoji_operation do
properties: %{
image_url: %Schema{type: :string},
tags: %Schema{type: :array, items: %Schema{type: :string}}
}
},
extensions: %{"x-additionalPropertiesName": "Emoji name"}
},
example: %{
"firefox" => %{
@ -45,7 +46,7 @@ def emoji_operation do
def frontend_configurations_operation do
%Operation{
tags: ["Configuration"],
tags: ["Others"],
summary: "Dump frontend configurations",
operationId: "UtilController.frontend_configurations",
parameters: [],
@ -53,7 +54,12 @@ def frontend_configurations_operation do
200 =>
Operation.response("List", "application/json", %Schema{
type: :object,
additionalProperties: %Schema{type: :object}
additionalProperties: %Schema{
type: :object,
description:
"Opaque object representing the instance-wide configuration for the frontend",
extensions: %{"x-additionalPropertiesName": "Frontend name"}
}
})
}
}
@ -132,7 +138,7 @@ defp change_email_request do
def update_notificaton_settings_operation do
%Operation{
tags: ["Accounts"],
tags: ["Settings"],
summary: "Update Notification Settings",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.update_notificaton_settings",
@ -207,6 +213,7 @@ def captcha_operation do
%Operation{
summary: "Get a captcha",
operationId: "UtilController.captcha",
tags: ["Others"],
parameters: [],
responses: %{
200 => Operation.response("Success", "application/json", %Schema{type: :object})
@ -357,7 +364,7 @@ defp delete_alias_request do
def healthcheck_operation do
%Operation{
tags: ["Accounts"],
tags: ["Others"],
summary: "Quick status check on the instance",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.healthcheck",
@ -372,7 +379,7 @@ def healthcheck_operation do
def remote_subscribe_operation do
%Operation{
tags: ["Accounts"],
tags: ["Remote interaction"],
summary: "Remote Subscribe",
operationId: "UtilController.remote_subscribe",
parameters: [],
@ -382,7 +389,7 @@ def remote_subscribe_operation do
def remote_interaction_operation do
%Operation{
tags: ["Accounts"],
tags: ["Remote interaction"],
summary: "Remote interaction",
operationId: "UtilController.remote_interaction",
requestBody: request_body("Parameters", remote_interaction_request(), required: true),
@ -408,7 +415,7 @@ defp remote_interaction_request do
def show_subscribe_form_operation do
%Operation{
tags: ["Accounts"],
tags: ["Remote interaction"],
summary: "Show remote subscribe form",
operationId: "UtilController.show_subscribe_form",
parameters: [],

View file

@ -145,7 +145,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
properties: %{
content: %Schema{
type: :object,
additionalProperties: %Schema{type: :string},
additionalProperties: %Schema{
type: :string,
description: "Alternate representation in the MIME type specified",
extensions: %{"x-additionalPropertiesName": "MIME type"}
},
description:
"A map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`"
},
@ -215,7 +219,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
},
spoiler_text: %Schema{
type: :object,
additionalProperties: %Schema{type: :string},
additionalProperties: %Schema{
type: :string,
description: "Alternate representation in the MIME type specified",
extensions: %{"x-additionalPropertiesName": "MIME type"}
},
description:
"A map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`."
},

View file

@ -6,7 +6,6 @@ defmodule Pleroma.Web.Feed.FeedView do
use Phoenix.HTML
use Pleroma.Web, :view
alias Pleroma.Formatter
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.Gettext
@ -72,7 +71,9 @@ def logo(user) do
def last_activity(activities), do: List.last(activities)
def activity_title(%{"content" => content, "summary" => summary} = data, opts \\ %{}) do
def activity_title(%{"content" => content} = data, opts \\ %{}) do
summary = Map.get(data, "summary", "")
title =
cond do
summary != "" -> summary
@ -81,9 +82,8 @@ def activity_title(%{"content" => content, "summary" => summary} = data, opts \\
end
title
|> Pleroma.Web.Metadata.Utils.scrub_html()
|> Pleroma.Emoji.Formatter.demojify()
|> Formatter.truncate(opts[:max_length], opts[:omission])
|> Pleroma.Web.Metadata.Utils.scrub_html_and_truncate(opts[:max_length], opts[:omission])
|> HtmlEntities.encode()
end
def activity_description(data) do

View file

@ -544,7 +544,12 @@ def blocks(%{assigns: %{user: user}} = conn, params) do
conn
|> add_link_headers(users)
|> render("index.json", users: users, for: user, as: :user)
|> render("index.json",
users: users,
for: user,
as: :user,
embed_relationships: embed_relationships?(params)
)
end
@doc "GET /api/v1/accounts/lookup"

View file

@ -34,7 +34,7 @@ def render("show.json", _) do
thumbnail:
URI.merge(Pleroma.Web.Endpoint.url(), Keyword.get(instance, :instance_thumbnail))
|> to_string,
languages: ["en"],
languages: Keyword.get(instance, :languages, ["en"]),
registrations: Keyword.get(instance, :registrations_open),
approval_required: Keyword.get(instance, :account_approval_required),
configuration: configuration(),

View file

@ -30,12 +30,13 @@ def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do
|> scrub_html_and_truncate_object_field(object)
end
def scrub_html_and_truncate(content, max_length \\ 200) when is_binary(content) do
def scrub_html_and_truncate(content, max_length \\ 200, omission \\ "...")
when is_binary(content) do
content
|> scrub_html
|> Emoji.Formatter.demojify()
|> HtmlEntities.decode()
|> Formatter.truncate(max_length)
|> Formatter.truncate(max_length, omission)
end
def scrub_html(content) when is_binary(content) do

View file

@ -38,10 +38,6 @@ def call(
def call(conn, _), do: conn
def checkpw(password, "$6" <> _ = password_hash) do
:crypt.crypt(password, password_hash) == password_hash
end
def checkpw(password, "$2" <> _ = password_hash) do
# Handle bcrypt passwords for Mastodon migration
Bcrypt.verify_pass(password, password_hash)
@ -60,10 +56,6 @@ def maybe_update_password(%User{password_hash: "$2" <> _} = user, password) do
do_update_password(user, password)
end
def maybe_update_password(%User{password_hash: "$6" <> _} = user, password) do
do_update_password(user, password)
end
def maybe_update_password(user, _), do: {:ok, user}
defp do_update_password(user, password) do

View file

@ -9,17 +9,13 @@ defmodule Pleroma.Web.RelMe do
recv_timeout: 2_000
]
if Pleroma.Config.get(:env) == :test do
def parse(url) when is_binary(url), do: parse_url(url)
else
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
def parse(url) when is_binary(url) do
@cachex.fetch!(:rel_me_cache, url, fn _ ->
{:commit, parse_url(url)}
end)
rescue
e -> {:error, "Cachex error: #{inspect(e)}"}
end
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
def parse(url) when is_binary(url) do
@cachex.fetch!(:rel_me_cache, url, fn _ ->
{:commit, parse_url(url)}
end)
rescue
e -> {:error, "Cachex error: #{inspect(e)}"}
end
def parse(_), do: {:error, "No URL provided"}

View file

@ -928,8 +928,7 @@ defmodule Pleroma.Web.Router do
end
scope "/", Pleroma.Web do
# Note: html format is supported only if static FE is enabled
pipe_through([:accepts_html_xml, :static_fe])
pipe_through([:accepts_html_xml])
get("/users/:nickname/feed", Feed.UserController, :feed, as: :user_feed)
end

View file

@ -4,8 +4,8 @@
<id><%= @data["id"] %></id>
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
<content type="html"><%= activity_description(@data) %></content>
<published><%= to_rfc3339(@activity.data["published"]) %></published>
<updated><%= to_rfc3339(@activity.data["published"]) %></updated>
<published><%= to_rfc3339(@data["published"]) %></published>
<updated><%= to_rfc3339(@data["published"]) %></updated>
<ostatus:conversation ref="<%= activity_context(@activity) %>">
<%= activity_context(@activity) %>
</ostatus:conversation>

View file

@ -4,7 +4,7 @@
<guid><%= @data["id"] %></guid>
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
<description><%= activity_description(@data) %></description>
<pubDate><%= to_rfc2822(@activity.data["published"]) %></pubDate>
<pubDate><%= to_rfc2822(@data["published"]) %></pubDate>
<ostatus:conversation ref="<%= activity_context(@activity) %>">
<%= activity_context(@activity) %>
</ostatus:conversation>

View file

@ -7,8 +7,8 @@
<id><%= @data["id"] %></id>
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
<content type="html"><%= activity_description(@data) %></content>
<published><%= to_rfc3339(@activity.data["published"]) %></published>
<updated><%= to_rfc3339(@activity.data["published"]) %></updated>
<published><%= to_rfc3339(@data["published"]) %></published>
<updated><%= to_rfc3339(@data["published"]) %></updated>
<ostatus:conversation ref="<%= activity_context(@activity) %>">
<%= activity_context(@activity) %>
</ostatus:conversation>

View file

@ -4,7 +4,7 @@
<guid isPermalink="true"><%= activity_context(@activity) %></guid>
<link><%= activity_context(@activity) %></link>
<pubDate><%= to_rfc2822(@activity.data["published"]) %></pubDate>
<pubDate><%= to_rfc2822(@data["published"]) %></pubDate>
<description><%= activity_description(@data) %></description>
<%= for attachment <- @data["attachment"] || [] do %>

View file

@ -13,6 +13,9 @@ def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do
{:ok, res}
else
{:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed}
{:error, :already_present} -> {:cancel, :already_present}
{:error, {:validate_object, reason}} -> {:cancel, reason}
{:error, {:error, {:validate, reason}}} -> {:cancel, reason}
{:error, {:reject, reason}} -> {:cancel, reason}
e -> e
end

View file

@ -8,7 +8,7 @@ def project do
app: :pleroma,
name: "Rebased",
compat_name: "Pleroma",
version: version("2.5.50"),
version: version("2.5.51"),
elixir: "~> 1.11",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
@ -156,9 +156,6 @@ defp deps do
{:sweet_xml, "~> 0.7.2"},
{:earmark, "~> 1.4.22"},
{:bbcode_pleroma, "~> 0.2.0"},
{:crypt,
git: "https://github.com/msantos/crypt.git",
ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"},
{:cors_plug, "~> 2.0"},
{:web_push_encryption, "~> 0.3.1"},
{:swoosh, "~> 1.8.2"},
@ -168,7 +165,7 @@ defp deps do
{:floki, "~> 0.27"},
{:timex, "~> 3.6"},
{:ueberauth, "~> 0.4"},
{:linkify, "~> 0.5.2"},
{:linkify, "~> 0.5.3"},
{:http_signatures, "~> 0.1.1"},
{:telemetry, "~> 1.0", override: true},
{:poolboy, "~> 1.5"},
@ -203,7 +200,7 @@ defp deps do
{:majic, "~> 1.0"},
{:eblurhash, "~> 1.2.2"},
{:oembed_providers, "~> 0.1.0"},
{:open_api_spex, "~> 3.10"},
{:open_api_spex, "~> 3.16"},
{:ecto_psql_extras, "~> 0.6"},
{:icalendar, "~> 1.1"},
{:geospatial, "~> 0.2.0"},

View file

@ -71,7 +71,7 @@
"joken": {:hex, :joken, "2.3.0", "62a979c46f2c81dcb8ddc9150453b60d3757d1ac393c72bb20fc50a7b0827dc6", [:mix], [{:jose, "~> 1.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "57b263a79c0ec5d536ac02d569c01e6b4de91bd1cb825625fe90eab4feb7bc1e"},
"jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"},
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
"linkify": {:hex, :linkify, "0.5.2", "fb66be139fdf1656ecb31f78a93592724d1b78d960a1b3598bd661013ea0e3c7", [:mix], [], "hexpm", "8d71ac690218d8952c90cbeb63cb8cc33738bb230d8a56d487d9447f2a5eab86"},
"linkify": {:hex, :linkify, "0.5.3", "5f8143d8f61f5ff08d3aeeff47ef6509492b4948d8f08007fbf66e4d2246a7f2", [:mix], [], "hexpm", "3ef35a1377d47c25506e07c1c005ea9d38d700699d92ee92825f024434258177"},
"majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
@ -93,7 +93,7 @@
"oauther": {:hex, :oauther, "1.3.0", "82b399607f0ca9d01c640438b34d74ebd9e4acd716508f868e864537ecdb1f76", [:mix], [], "hexpm", "78eb888ea875c72ca27b0864a6f550bc6ee84f2eeca37b093d3d833fbcaec04e"},
"oban": {:hex, :oban, "2.13.4", "b4c4f48f4c89cc01036670eefa28aa9c03d09aadd402655475b936983d597006", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7d26f82b409e2d7928fbb75a17716e06ad3f783ebe9af260e3dd23abed7f124"},
"oembed_providers": {:hex, :oembed_providers, "0.1.0", "9b336ee5f3ca20ee4ed005383c74b154d30d0abeb98e95828855c0e2841ae46b", [:mix], [{:glob, "~> 1.0", [hex: :glob, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "ac1dda0f743aa6fdead3eef59decfefc9de91d550bf0805b8fce16ed10d421ba"},
"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"},
"open_api_spex": {:hex, :open_api_spex, "3.16.0", "9843af4e87550cd8ac5821b10e4c74f1d51f0d4e3310f824d780614743423b25", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:ymlr, "~> 2.0 or ~> 3.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "bb0be24a648b73e8fc8cbda17f514b8486262275e8b33e8b5ae66283df972129"},
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm", "639b2e8749e11b87b9eb42f2ad325d161c170b39b288ac8d04c4f31f8f0823eb"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},

View file

@ -6033,3 +6033,15 @@ msgstr ""
msgctxt "config label at :pleroma-:instance > :moderator_privileges"
msgid "Moderator privileges"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/pleroma/docs/translator.ex:5
msgctxt "config description at :pleroma-:instance > :languages"
msgid "Languages to be exposed in /api/v1/instance. Should be in the format of BCP47 language codes."
msgstr ""
#, elixir-autogen, elixir-format
#: lib/pleroma/docs/translator.ex:5
msgctxt "config label at :pleroma-:instance > :languages"
msgid "Languages"
msgstr ""

View file

@ -111,7 +111,7 @@ msgid "Can't display this activity"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:337
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334
msgid "Can't find user"
msgstr ""
@ -236,7 +236,7 @@ msgid "Poll's author can't vote"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:502
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:499
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51
@ -558,7 +558,7 @@ msgid "Access denied"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:331
msgid "This API requires an authenticated user"
msgstr ""

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

BIN
test/fixtures/image_with_stray_data_after.png vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View file

@ -0,0 +1,62 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.OpenapiSpecTest do
use Pleroma.DataCase, async: true
alias Mix.Tasks.Pleroma.OpenapiSpec
@spec_base %{
"paths" => %{
"/cofe" => %{
"get" => %{
"operationId" => "Some.operation",
"tags" => []
}
},
"/mew" => %{
"post" => %{
"operationId" => "Another.operation",
"tags" => ["mew mew"]
}
}
},
"x-tagGroups" => [
%{
"name" => "mew",
"tags" => ["mew mew", "abc"]
},
%{
"name" => "lol",
"tags" => ["lol lol", "xyz"]
}
]
}
describe "check_specs/1" do
test "Every operation must have a tag" do
assert {:error, ["Some.operation (get /cofe): No tags specified"]} ==
OpenapiSpec.check_specs(@spec_base)
end
test "Every tag must be in tag groups" do
spec =
@spec_base
|> put_in(["paths", "/cofe", "get", "tags"], ["abc", "def", "not specified"])
assert {:error,
[
"Some.operation (get /cofe): Tags #{inspect(["def", "not specified"])} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
]} == OpenapiSpec.check_specs(spec)
end
test "No errors if ok" do
spec =
@spec_base
|> put_in(["paths", "/cofe", "get", "tags"], ["abc", "mew mew"])
assert :ok == OpenapiSpec.check_specs(spec)
end
end
end

View file

@ -476,6 +476,32 @@ test "it disables notifications from strangers" do
refute Notification.create_notification(activity, followed)
end
test "it disables notifications from non-followees" do
follower = insert(:user)
followed =
insert(:user,
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
)
CommonAPI.follow(follower, followed)
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
refute Notification.create_notification(activity, followed)
end
test "it allows notifications from followees" do
poster = insert(:user)
receiver =
insert(:user,
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
)
CommonAPI.follow(receiver, poster)
{:ok, activity} = CommonAPI.post(poster, %{status: "hey @#{receiver.nickname}"})
assert Notification.create_notification(activity, receiver)
end
test "it doesn't create a notification for user if he is the activity author" do
activity = insert(:note_activity)
author = User.get_cached_by_ap_id(activity.data["actor"])
@ -1394,5 +1420,32 @@ test "it returns notifications about favorites with filtered word", %{user: user
assert length(Notification.for_user(user)) == 1
end
test "it returns notifications when related object is without content and filters are defined",
%{user: user} do
followed_user = insert(:user, is_locked: true)
insert(:filter, user: followed_user, phrase: "test", hide: true)
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
refute FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
assert %{type: "follow_request"} =
NotificationView.render("show.json", %{
notification: notification,
for: followed_user
})
assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
assert %{type: "follow"} =
NotificationView.render("show.json", %{
notification: notification,
for: followed_user
})
end
end
end

View file

@ -42,6 +42,33 @@ test "otherwise returns ImageDescription when present" do
{:ok, :filtered, uploads_after}
end
test "Ignores warnings" do
uploads = %Pleroma.Upload{
name: "image_with_imagedescription_and_caption-abstract_and_stray_data_after.png",
content_type: "image/png",
path:
Path.absname(
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
),
tempfile:
Path.absname(
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
)
}
assert {:ok, :filtered, %{description: "a descriptive white pixel"}} =
Filter.Exiftool.ReadDescription.filter(uploads)
uploads = %Pleroma.Upload{
name: "image_with_stray_data_after.png",
content_type: "image/png",
path: Path.absname("test/fixtures/image_with_stray_data_after.png"),
tempfile: Path.absname("test/fixtures/image_with_stray_data_after.png")
}
assert {:ok, :filtered, %{description: nil}} = Filter.Exiftool.ReadDescription.filter(uploads)
end
test "otherwise returns iptc:Caption-Abstract when present" do
upload = %Pleroma.Upload{
name: "image_with_caption-abstract.jpg",

View file

@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.ImportTest do
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User

View file

@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserSearchTest do
alias Pleroma.Repo
alias Pleroma.User
use Pleroma.DataCase

View file

@ -104,6 +104,7 @@ test "it does not fetch reply-to activities beyond max replies depth limit" do
end
end
@tag capture_log: true
test "it does not crash if the object in inReplyTo can't be fetched" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")
@ -834,6 +835,7 @@ test "the standalone note uses its own ID when context is missing" do
assert modified.data["context"] == object.data["id"]
end
@tag capture_log: true
test "the reply note uses its parent's ID when context is missing and reply is unreachable" do
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")

View file

@ -316,6 +316,7 @@ test "create new config setting in db", %{conn: conn} do
assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
end
@tag capture_log: true
test "save configs setting without explicit key", %{conn: conn} do
adapter = Application.get_env(:http, :adapter)
send_user_agent = Application.get_env(:http, :send_user_agent)

View file

@ -398,6 +398,34 @@ test "returns reports with specified assigned user", %{conn: conn, admin: admin}
assert response["total"] == 1
end
test "renders content correctly", %{conn: conn} do
[reporter, target_user] = insert_pair(:user)
note = insert(:note, user: target_user, data: %{"content" => "mew 1"})
note2 = insert(:note, user: target_user, data: %{"content" => "mew 2"})
activity = insert(:note_activity, user: target_user, note: note)
activity2 = insert(:note_activity, user: target_user, note: note2)
{:ok, _report} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel offended",
status_ids: [activity.id, activity2.id]
})
CommonAPI.delete(activity.id, target_user)
CommonAPI.delete(activity2.id, target_user)
response =
conn
|> get(report_path(conn, :index))
|> json_response_and_validate_schema(:ok)
assert [open_report] = response["reports"]
assert %{"statuses" => [s1, s2]} = open_report
assert "mew 1" in [s1["content"], s2["content"]]
assert "mew 2" in [s1["content"], s2["content"]]
end
test "returns 403 when requested by a non-admin" do
user = insert(:user)
token = insert(:oauth_token, user: user)

View file

@ -519,6 +519,25 @@ test "it de-duplicates tags" do
assert Object.tags(object) == ["2hu"]
end
test "zwnj is treated as word character" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#ساٴين‌س"})
object = Object.normalize(activity, fetch: false)
assert Object.tags(object) == ["ساٴين‌س"]
end
test "double dot in link is allowed" do
user = insert(:user)
text = "https://example.to/something..mp3"
{:ok, activity} = CommonAPI.post(user, %{status: text})
object = Object.normalize(activity, fetch: false)
assert object.data["content"] == "<a href=\"#{text}\" rel=\"ugc\">#{text}</a>"
end
test "it adds emoji in the object" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: ":firefox:"})

View file

@ -133,7 +133,7 @@ test "successfully processes incoming AP docs with correct origin" do
assert {:ok, _activity} = ObanHelpers.perform(job)
assert {:ok, job} = Federator.incoming_ap_doc(params)
assert {:error, :already_present} = ObanHelpers.perform(job)
assert {:cancel, :already_present} = ObanHelpers.perform(job)
end
test "rejects incoming AP docs with incorrect origin" do

View file

@ -57,9 +57,23 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
)
note_activity2 = insert(:note_activity, note: note2)
note3 =
insert(:note,
user: user,
data: %{
"content" => "This note tests whether HTML entities are truncated properly",
"summary" => "Won't, didn't fail",
"inReplyTo" => note_activity2.id
}
)
_note_activity3 = insert(:note_activity, note: note3)
object = Object.normalize(note_activity, fetch: false)
[user: user, object: object, max_id: note_activity2.id]
encoded_title = FeedView.activity_title(note3.data)
[user: user, object: object, max_id: note_activity2.id, encoded_title: encoded_title]
end
test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do
@ -74,7 +88,7 @@ test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
assert activity_titles == ['2hu', '2hu & as']
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
@ -105,7 +119,7 @@ test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id
|> SweetXml.parse()
|> SweetXml.xpath(~x"//item/title/text()"l)
assert activity_titles == ['2hu', '2hu & as']
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
@ -176,6 +190,30 @@ test "does not require authentication on non-federating instances", %{conn: conn
|> get("/users/#{user.nickname}/feed.rss")
|> response(200)
end
test "does not mangle HTML entities midway", %{
conn: conn,
user: user,
object: object,
encoded_title: encoded_title
} do
resp =
conn
|> put_req_header("accept", "application/atom+xml")
|> get(user_feed_path(conn, :feed, user.nickname))
|> response(200)
activity_titles =
resp
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
assert resp =~ FeedView.escape(object.data["content"])
assert resp =~ FeedView.escape(object.data["summary"])
assert resp =~ FeedView.escape(object.data["context"])
assert resp =~ encoded_title
end
end
# Note: see ActivityPubControllerTest for JSON format tests

View file

@ -2045,6 +2045,39 @@ test "getting a list of blocks" do
assert [%{"id" => ^id1}] = result
end
test "list of blocks with with_relationships parameter" do
%{user: user, conn: conn} = oauth_access(["read:blocks"])
%{id: id1} = other_user1 = insert(:user)
%{id: id2} = other_user2 = insert(:user)
%{id: id3} = other_user3 = insert(:user)
{:ok, _, _} = User.follow(other_user1, user)
{:ok, _, _} = User.follow(other_user2, user)
{:ok, _, _} = User.follow(other_user3, user)
{:ok, _} = User.block(user, other_user1)
{:ok, _} = User.block(user, other_user2)
{:ok, _} = User.block(user, other_user3)
assert [
%{
"id" => ^id3,
"pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
},
%{
"id" => ^id2,
"pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
},
%{
"id" => ^id1,
"pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
}
] =
conn
|> get("/api/v1/blocks?with_relationships=true")
|> json_response_and_validate_schema(200)
end
test "account lookup", %{conn: conn} do
%{nickname: acct} = insert(:user, %{nickname: "nickname"})
%{nickname: acct_two} = insert(:user, %{nickname: "nickname@notlocaldoma.in"})

View file

@ -181,4 +181,18 @@ test "returns empty array if mrf transparency is disabled", %{conn: conn} do
assert [] == json_response_and_validate_schema(conn, 200)
end
end
test "instance languages", %{conn: conn} do
assert %{"languages" => ["en"]} =
conn
|> get("/api/v1/instance")
|> json_response_and_validate_schema(200)
clear_config([:instance, :languages], ["aa", "bb"])
assert %{"languages" => ["aa", "bb"]} =
conn
|> get("/api/v1/instance")
|> json_response_and_validate_schema(200)
end
end

View file

@ -382,7 +382,9 @@ test "updates the user's background, upload_limit, returns a HTTP 413", %{
"pleroma_background_image" => new_background_oversized
})
assert user_response = json_response_and_validate_schema(res, 413)
assert %{"error" => "File is too large"} == json_response_and_validate_schema(res, 413)
user = Repo.get(User, user.id)
assert user.background == %{}
clear_config([:instance, :upload_limit], upload_limit)

View file

@ -72,7 +72,7 @@ test "it does not return old content after editing" do
end
end
describe "scrub_html_and_truncate/2" do
describe "scrub_html_and_truncate/3" do
test "it returns text without encode HTML" do
assert Utils.scrub_html_and_truncate("Pleroma's really cool!") == "Pleroma's really cool!"
end

View file

@ -70,28 +70,6 @@ test "with a bcrypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
assert "$pbkdf2" <> _ = user.password_hash
end
@tag :skip_on_mac
test "with a crypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
user =
insert(:user,
password_hash:
"$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
)
conn =
conn
|> assign(:auth_user, user)
|> assign(:auth_credentials, %{password: "password"})
|> AuthenticationPlug.call(%{})
assert conn.assigns.user.id == conn.assigns.auth_user.id
assert conn.assigns.token == nil
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
user = User.get_by_id(user.id)
assert "$pbkdf2" <> _ = user.password_hash
end
describe "checkpw/2" do
test "check pbkdf2 hash" do
hash =
@ -101,14 +79,6 @@ test "check pbkdf2 hash" do
refute AuthenticationPlug.checkpw("test-password1", hash)
end
@tag :skip_on_mac
test "check sha512-crypt hash" do
hash =
"$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
assert AuthenticationPlug.checkpw("password", hash)
end
test "check bcrypt hash" do
hash = "$2a$10$uyhC/R/zoE1ndwwCtMusK.TLVzkQ/Ugsbqp3uXI.CTTz0gBw.24jS"

View file

@ -11,7 +11,7 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do
alias Pleroma.Workers.ReceiverWorker
test "it ignores MRF reject" do
test "it does not retry MRF reject" do
params = insert(:note).data
with_mock Pleroma.Web.ActivityPub.Transmogrifier,
@ -22,4 +22,31 @@ test "it ignores MRF reject" do
})
end
end
test "it does not retry ObjectValidator reject" do
params =
insert(:note_activity).data
|> Map.put("id", Pleroma.Web.ActivityPub.Utils.generate_activity_id())
|> Map.put("object", %{
"type" => "Note",
"id" => Pleroma.Web.ActivityPub.Utils.generate_object_id()
})
with_mock Pleroma.Web.ActivityPub.ObjectValidator, [:passthrough],
validate: fn _, _ -> {:error, %Ecto.Changeset{}} end do
assert {:cancel, {:error, %Ecto.Changeset{}}} =
ReceiverWorker.perform(%Oban.Job{
args: %{"op" => "incoming_ap_doc", "params" => params}
})
end
end
test "it does not retry duplicates" do
params = insert(:note_activity).data
assert {:cancel, :already_present} =
ReceiverWorker.perform(%Oban.Job{
args: %{"op" => "incoming_ap_doc", "params" => params}
})
end
end

View file

@ -2,6 +2,8 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
Code.put_compiler_option(:warnings_as_errors, true)
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: []
ExUnit.start(exclude: [:federated, :erratic] ++ os_exclude)