Compare commits

...

11 commits

Author SHA1 Message Date
c0a99df06a Merge remote-tracking branch 'oneric/varfixes' into develop
Some checks are pending
ci/woodpecker/push/build-amd64 Pipeline is pending approval
ci/woodpecker/push/build-arm64 Pipeline is pending approval
ci/woodpecker/push/docs Pipeline is pending approval
ci/woodpecker/push/lint Pipeline is pending approval
ci/woodpecker/push/test Pipeline is pending approval
2024-10-30 15:15:00 +00:00
a3101a435b Fix swagger-ui
Some checks are pending
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build-amd64 Pipeline was successful
ci/woodpecker/pr/build-arm64 Pipeline was successful
ci/woodpecker/pr/docs Pipeline was successful
ci/woodpecker/pull_request_closed/build-amd64 Pipeline is pending approval
ci/woodpecker/pull_request_closed/build-arm64 Pipeline is pending approval
ci/woodpecker/pull_request_closed/docs Pipeline is pending approval
ci/woodpecker/pull_request_closed/lint Pipeline is pending approval
ci/woodpecker/pull_request_closed/test Pipeline is pending approval
Ever since the browser frontend switcher was introduced in
de64c6c54a /akkoma counts as
an API prefix and thus gets skipped by frontend plugs
breaking the old swagger ui path of /akkoma/swagger-ui.

Do the simple thing and change the frontend path to
/pleroma/swaggerui which isn't an API path and can't collide
with frontend user paths given pleroma is areserved nickname.

Reported in
  https://meta.akkoma.dev/t/view-all-endpoints/269/7
  https://meta.akkoma.dev/t/swagger-ui-not-loading/728
2024-06-27 18:29:45 +02:00
d488cf476e Fix voters count field
Mastodon API demands this be null unless it’s a multi-selection poll.
Not abiding by this can mess up display in some clients.

Fixes: #190
2024-06-27 18:29:45 +02:00
ca182a0ae7 Correctly parse content types with multiple profiles
Multiple profiles can be specified as a space-separated list
and the possibility of additional profiles is explicitly brought up
in ActivityStream spec
2024-06-27 18:29:45 +02:00
495a1a71e8 strip_metadata: skip BMP files
Not _yet_ supported as of exiftool 12.87, though
at first glance it seems like standard BMP files
can't store any metadata besides colour profiles

Fixes the specific case from
AkkomaGang/akkoma-fe#396
although the frontend shouldn’t get bricked regardless.
2024-06-27 18:29:45 +02:00
cf19d4901f Disable Ecto query logging in tests
The debug logs are very noisy and can be enabled during analysis
of a specific error believed to be SQL-related

--

Before log capturing those debug messages were still hidden,
but with log capturing they show up in the output of failed
tests unless disabled.

Cherry-picked-from: e628d00a81
2024-06-27 18:29:45 +02:00
07539f7825 Hide logs during test unless a test fails
Currently `mix test` prints a slew of logs in the terminal
with messages from different tests intermsparsed. Globally
enabling capture log hides log messages unless a test fails
reducing noise and making it easier to anylse the important
(from failed tests) messages.

Compiler warnings and a few messages not printed via Logger
still show up but its much more readable than before.

Ported from: 3aed111a42
2024-06-27 18:29:45 +02:00
0ab2f2ab45 ci: retry failed tasks once
We have a bunch of mysterious sporadic failures which usually disappear
when rerunning failed jobs only. Ideally we should locate and fix the
cause of those psoradic failures, but until we figure this out retrying
once makes CI status less useless.
2024-06-27 18:29:45 +02:00
95ed4931f8 docs: note frontend tasks need to be run as akkoma user
Fixes: #748
2024-06-27 18:29:45 +02:00
7cd3954152 Remove superfluous actor key suffix
Fragments are already always stripped anyway
so listing one specific fragment here is
unnecessary and potentially confusing.

This effectively reverts
4457928e32
but keeps the added bridgy testcase.
2024-06-27 18:29:45 +02:00
80a4e30be7 Upgrade captach dep
Fixes a deprecation warning showing up each mix call
when using elixir 1.17
2024-06-27 18:29:45 +02:00
30 changed files with 74 additions and 42 deletions

View file

@ -87,5 +87,5 @@ steps:
- mix ecto.create
- mix ecto.migrate
- mkdir -p test/tmp
- mix test --preload-modules --exclude erratic --exclude federated --exclude mocked
- mix test --preload-modules --only mocked
- mix test --preload-modules --exclude erratic --exclude federated --exclude mocked || mix test --failed
- mix test --preload-modules --only mocked || mix test --failed

View file

@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## BREAKING
- Minimum PostgreSQL version is raised to 12
- Swagger UI moved from `/akkoma/swaggerui/` to `/pleroma/swaggerui/`
## Added
- Implement [FEP-67ff](https://codeberg.org/fediverse/fep/src/branch/main/fep/67ff/fep-67ff.md) (federation documentation)
@ -19,6 +20,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Meilisearch: order of results returned from our REST API now actually matches how Meilisearch ranks results
- Emoji are now federated as anonymous objects, fixing issues with
some strict servers e.g. rejecting e.g. remote emoji reactions
- AP objects with additional JSON-LD profiles beyond ActivityStreams can now be fetched
- Single-selection polls no longer expose the voter_count; MastoAPI demands it be null
and this confused some clients leading to vote distributions >100%
## Changed
- Refactored Rich Media to cache the content in the database. Fetching operations that could block status rendering have been eliminated.

View file

@ -51,7 +51,8 @@
hostname: System.get_env("DB_HOST") || "localhost",
pool: Ecto.Adapters.SQL.Sandbox,
pool_size: 50,
queue_target: 5000
queue_target: 5000,
log: false
config :pleroma, :dangerzone, override_repo_pool_size: true

View file

@ -338,7 +338,7 @@ config :pleroma, :frontends,
* `:primary` - The frontend that will be served at `/`
* `:admin` - The frontend that will be served at `/pleroma/admin`
* `:swagger` - Config for developers to act as an API reference to be served at `/akkoma/swaggerui/` (trailing slash _needed_). Disabled by default.
* `:swagger` - Config for developers to act as an API reference to be served at `/pleroma/swaggerui/` (trailing slash _needed_). Disabled by default.
* `:mastodon` - The mastodon-fe configuration. This shouldn't need to be changed. This is served at `/web` when installed.
### :static\_fe

View file

@ -60,4 +60,4 @@ config :pleroma, :frontends,
Then run the [pleroma.frontend cli task](../../administration/CLI_tasks/frontend) with the name of `swagger-ui` to install the distribution files.
You will now be able to view documentation at `/akkoma/swaggerui`
You will now be able to view documentation at `/pleroma/swaggerui`

View file

@ -6,7 +6,9 @@ probably install frontends.
These are no longer bundled with the distribution and need an extra
command to install.
For most installations, the following will suffice:
You **must** run frontend management tasks as the akkoma user,
the same way you downloaded the build or cloned the git repo before.
But otherwise, for most installations, the following will suffice:
=== "OTP"
```sh
@ -28,4 +30,3 @@ For most installations, the following will suffice:
```
For more customised installations, refer to [Frontend Management](../../configuration/frontend_management)

View file

@ -369,8 +369,12 @@ def get_object(id) do
{"activity+json", _} ->
{:ok, final_id, body}
{"ld+json", %{"profile" => "https://www.w3.org/ns/activitystreams"}} ->
{:ok, final_id, body}
{"ld+json", %{"profile" => profiles}} ->
if "https://www.w3.org/ns/activitystreams" in String.split(profiles) do
{:ok, final_id, body}
else
{:error, {:content_type, content_type}}
end
_ ->
{:error, {:content_type, content_type}}

View file

@ -18,6 +18,7 @@ defmodule Pleroma.Upload.Filter.Exiftool.StripMetadata do
# Formats not compatible with exiftool at this time
def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop}
def filter(%Pleroma.Upload{content_type: "image/bmp"}), do: {:ok, :noop}
def filter(%Pleroma.Upload{content_type: "image/svg+xml"}), do: {:ok, :noop}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do

View file

@ -32,7 +32,9 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Poll do
},
voters_count: %Schema{
type: :integer,
description: "How many unique accounts have voted. Number."
nullable: true,
description:
"How many unique accounts have voted for a multi-selection poll. Number, or null if single-selection poll."
},
voted: %Schema{
type: :boolean,

View file

@ -66,10 +66,10 @@ defmodule Pleroma.Web.Endpoint do
}
)
plug(Plug.Static.IndexHtml, at: "/akkoma/swaggerui")
plug(Plug.Static.IndexHtml, at: "/pleroma/swaggerui/")
plug(Pleroma.Web.Plugs.FrontendStatic,
at: "/akkoma/swaggerui",
at: "/pleroma/swaggerui",
frontend_type: :swagger,
gzip: true,
if: &Pleroma.Web.Swagger.ui_enabled?/0,

View file

@ -19,7 +19,7 @@ def render("show.json", %{object: object, multiple: multiple, options: options}
expired: expired,
multiple: multiple,
votes_count: votes_count,
voters_count: voters_count(object),
voters_count: voters_count(multiple, object),
options: options,
emojis: Pleroma.Web.MastodonAPI.StatusView.build_emojis(object.data["emoji"])
}
@ -68,11 +68,19 @@ defp options_and_votes_count(options) do
end)
end
defp voters_count(%{data: %{"voters" => voters}}) when is_list(voters) do
defp voters_count(false, _poll_data) do
# Mastodon always sets voter count to "null" unless multiple options were selectable
# Some clients may rely on this to detect multiple selection polls and it can mess
# up percentages for some clients if we never got a correct remote voter count and
# only count local voters here; see https://akkoma.dev/AkkomaGang/akkoma/issues/190
nil
end
defp voters_count(_multiple, %{data: %{"voters" => voters}}) when is_list(voters) do
length(voters)
end
defp voters_count(_), do: 0
defp voters_count(_, _), do: 0
defp voted_and_own_votes(%{object: object} = params, options) do
if params[:for] do

View file

@ -180,7 +180,7 @@ defp deps do
{:remote_ip, "~> 1.1.0"},
{:captcha,
git: "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git",
ref: "90f6ce7672f70f56708792a98d98bd05176c9176"},
ref: "6630c42aaaab124e697b4e513190c89d8b64e410"},
{:restarter, path: "./restarter"},
{:majic,
git: "https://akkoma.dev/AkkomaGang/majic.git",

View file

@ -7,7 +7,7 @@
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"cachex": {:hex, :cachex, "3.6.0", "14a1bfbeee060dd9bec25a5b6f4e4691e3670ebda28c8ba2884b12fe30b36bf8", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "ebf24e373883bc8e0c8d894a63bbe102ae13d918f790121f5cfe6e485cc8e2e2"},
"calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.1.201603 or ~> 0.5.20 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"},
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "90f6ce7672f70f56708792a98d98bd05176c9176", [ref: "90f6ce7672f70f56708792a98d98bd05176c9176"]},
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "6630c42aaaab124e697b4e513190c89d8b64e410", [ref: "6630c42aaaab124e697b4e513190c89d8b64e410"]},
"castore": {:hex, :castore, "1.0.9", "5cc77474afadf02c7c017823f460a17daa7908e991b0cc917febc90e466a375c", [:mix], [], "hexpm", "5ea956504f1ba6f2b4eb707061d8e17870de2bee95fb59d512872c2ef06925e7"},
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},

View file

@ -51,7 +51,6 @@ test "error if file with custom settings doesn't exist" do
clear_config(:configurable_from_database, true)
end
@tag capture_log: true
test "config migration refused when deprecated settings are found" do
clear_config([:media_proxy, :whitelist], ["domain_without_scheme.com"])
assert config_records() == []

View file

@ -203,7 +203,6 @@ defp spoofed_object_with_ids(
:ok
end
@tag capture_log: true
test "it works when fetching the OP actor errors out" do
# Here we simulate a case where the author of the OP can't be read
assert {:ok, _} =
@ -779,7 +778,7 @@ test "should return ok if the content type is application/activity+json" do
assert {:ok, _, "{}"} = Fetcher.get_object("https://mastodon.social/2")
end
test "should return ok if the content type is application/ld+json with a profile" do
test "should return ok if the content type is application/ld+json with the ActivityStream profile" do
Tesla.Mock.mock(fn
%{
method: :get,
@ -799,6 +798,26 @@ test "should return ok if the content type is application/ld+json with a profile
assert {:ok, _, "{}"} = Fetcher.get_object("https://mastodon.social/2")
end
test "should return ok if the content type is application/ld+json with several profiles" do
Tesla.Mock.mock(fn
%{
method: :get,
url: "https://mastodon.social/2"
} ->
%Tesla.Env{
status: 200,
url: "https://mastodon.social/2",
headers: [
{"content-type",
"application/ld+json; profile=\"https://example.org/ns/superduperspec https://www.w3.org/ns/activitystreams\""}
],
body: "{}"
}
end)
assert {:ok, _, "{}"} = Fetcher.get_object("https://mastodon.social/2")
end
test "should not return ok with other content types" do
Tesla.Mock.mock(fn
%{

View file

@ -6,7 +6,6 @@ defmodule Pleroma.SignatureTest do
use Pleroma.DataCase, async: false
@moduletag :mocked
import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
import Mock

View file

@ -115,6 +115,15 @@ test "verify webp files are skipped" do
assert Filter.Exiftool.StripMetadata.filter(upload) == {:ok, :noop}
end
test "verify bmp files are skipped" do
upload = %Pleroma.Upload{
name: "sample.bmp",
content_type: "image/bmp"
}
assert Filter.Exiftool.StripMetadata.filter(upload) == {:ok, :noop}
end
test "verify svg files are skipped" do
upload = %Pleroma.Upload{
name: "sample.svg",

View file

@ -815,7 +815,6 @@ test "gets an existing user by fully qualified nickname, case insensitive" do
assert user == fetched_user
end
@tag capture_log: true
test "returns nil if no user could be fetched" do
{:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant@social.heldscal.la")
assert fetched_user == "not found nonexistant@social.heldscal.la"
@ -872,7 +871,6 @@ test "if nicknames clash, the old user gets a prefix with the old id to the nick
assert orig_user.nickname == "#{orig_user.id}.admin@mastodon.example.org"
end
@tag capture_log: true
test "it returns the old user if stale, but unfetchable" do
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)

View file

@ -573,7 +573,6 @@ test "it inserts an incoming activity into the database", %{conn: conn} do
assert Activity.get_by_ap_id(data["id"])
end
@tag capture_log: true
test "it inserts an incoming activity into the database" <>
"even if we can't fetch the user but have it in our db",
%{conn: conn} do
@ -1114,7 +1113,6 @@ test "it clears `unreachable` federation status of the sender", %{conn: conn, da
assert Instances.reachable?(sender_host)
end
@tag capture_log: true
test "it removes all follower collections but actor's", %{conn: conn} do
[actor, recipient] = insert_pair(:user)
actor = with_signing_key(actor)
@ -1179,7 +1177,6 @@ test "it requires authentication", %{conn: conn} do
assert json_response(ret_conn, 200)
end
@tag capture_log: true
test "forwarded report", %{conn: conn} do
admin = insert(:user, is_admin: true)
@ -1260,7 +1257,6 @@ test "forwarded report", %{conn: conn} do
)
end
@tag capture_log: true
test "forwarded report from mastodon", %{conn: conn} do
admin = insert(:user, is_admin: true)
actor = insert(:user, local: false)

View file

@ -114,7 +114,6 @@ test "returns error when activity not `Create` type" do
assert Relay.publish(activity) == {:error, "Not implemented"}
end
@tag capture_log: true
test "returns error when activity not public" do
activity = insert(:direct_note_activity)
assert Relay.publish(activity) == {:error, false}

View file

@ -83,7 +83,6 @@ test "it works for incoming announces, fetching the announced object" do
assert(Activity.get_create_by_object_ap_id(data["object"]))
end
@tag capture_log: true
test "it works for incoming announces with an existing activity" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
@ -136,7 +135,6 @@ test "it works for incoming announces with an inlined activity" do
assert object.data["content"] == "this is a private toot"
end
@tag capture_log: true
test "it rejects incoming announces with an inlined activity from another origin" do
Tesla.Mock.mock(fn
%{method: :get} -> %Tesla.Env{status: 404, body: ""}

View file

@ -86,7 +86,6 @@ test "it fails for incoming deletes with spoofed origin" do
assert match?({:error, _}, Transmogrifier.handle_incoming(data))
end
@tag capture_log: true
test "it works for incoming user deletes" do
%{ap_id: ap_id} = insert(:user, ap_id: "http://mastodon.example.org/users/admin")

View file

@ -57,7 +57,6 @@ test "it ignores an incoming notice if we already have it" do
assert activity == returned_activity
end
@tag capture_log: true
test "it fetches reply-to activities if we don't have them" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")
@ -537,7 +536,6 @@ test "returns object with inReplyTo when denied incoming reply", %{data: data} d
assert modified_object["inReplyTo"] == []
end
@tag capture_log: true
test "returns modified object when allowed incoming reply", %{data: data} do
object_with_reply =
Map.put(

View file

@ -561,7 +561,6 @@ test "returns nil when cannot normalize object" do
end) =~ ":valid_uri_scheme"
end
@tag capture_log: true
test "returns {:ok, %Object{}} for success case" do
assert {:ok, %Object{}} =
Transmogrifier.get_obj_helper(

View file

@ -79,7 +79,6 @@ test "search", %{conn: conn} do
assert status["id"] == to_string(activity.id)
end
@tag capture_log: true
test "constructs hashtags from search query", %{conn: conn} do
results =
conn

View file

@ -152,7 +152,6 @@ test "filtering", %{conn: conn, user: user} do
end
describe "public" do
@tag capture_log: true
test "the public timeline", %{conn: conn} do
user = insert(:user)
@ -810,7 +809,6 @@ test "filtering", %{user: user, conn: conn} do
describe "hashtag" do
setup do: oauth_access(["n/a"])
@tag capture_log: true
test "hashtag timeline", %{conn: conn} do
following = insert(:user)

View file

@ -43,7 +43,7 @@ test "renders a poll" do
%{title: "why are you even asking?", votes_count: 0}
],
votes_count: 0,
voters_count: 0
voters_count: nil
}
result = PollView.render("show.json", %{object: object})

View file

@ -67,7 +67,6 @@ test "performs sending notifications" do
assert Impl.perform(notif) == {:ok, [:ok, :ok]}
end
@tag capture_log: true
test "returns error if notif does not match " do
assert Impl.perform(%{}) == {:error, :unknown_type}
end
@ -76,7 +75,6 @@ test "successful message sending" do
assert Impl.push_message(@message, @sub, @api_key, %Subscription{}) == :ok
end
@tag capture_log: true
test "fail message sending" do
assert Impl.push_message(
@message,

View file

@ -190,7 +190,6 @@ test "prevents spoofing" do
end
end
@tag capture_log: true
test "prevents forgeries" do
Tesla.Mock.mock(fn
%{url: "https://bad.com/.well-known/webfinger?resource=acct:meanie@bad.com"} ->

View file

@ -3,7 +3,11 @@
# SPDX-License-Identifier: AGPL-3.0-only
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: []
ExUnit.start(exclude: [:federated, :erratic] ++ os_exclude)
ExUnit.start(
capture_log: true,
exclude: [:federated, :erratic] ++ os_exclude
)
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual)