Merge remote-tracking branch 'origin/develop' into fork
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
commit
e0d0992e10
39 changed files with 450 additions and 91 deletions
1
changelog.d/fix-mrfs.add
Normal file
1
changelog.d/fix-mrfs.add
Normal file
|
@ -0,0 +1 @@
|
|||
Added a Mix task "pleroma.config fix_mrf_policies" which will remove erroneous MRF policies from ConfigDB.
|
1
changelog.d/handle-non-validate-delete-errors.change
Normal file
1
changelog.d/handle-non-validate-delete-errors.change
Normal file
|
@ -0,0 +1 @@
|
|||
Transmogrifier: handle non-validate errors on incoming Delete activities
|
1
changelog.d/metadata-provider-empty-post.fix
Normal file
1
changelog.d/metadata-provider-empty-post.fix
Normal file
|
@ -0,0 +1 @@
|
|||
Fix OpenGraph and Twitter metadata providers when parsing objects with no content or summary fields.
|
1
changelog.d/oban-cancel-federation.add
Normal file
1
changelog.d/oban-cancel-federation.add
Normal file
|
@ -0,0 +1 @@
|
|||
Deleting, Unfavoriting, Unrepeating, or Unreacting will cancel undelivered publishing jobs for the original activity.
|
1
changelog.d/oban-cancel.change
Normal file
1
changelog.d/oban-cancel.change
Normal file
|
@ -0,0 +1 @@
|
|||
Changed some jobs to return :cancel on unrecoverable errors that should not be retried
|
|
@ -1 +1 @@
|
|||
Discard Remote Fetcher jobs which errored due to an MRF rejection
|
||||
Discard Remote Fetcher jobs which errored due to an MRF rejection.
|
||||
|
|
1
changelog.d/oban-live_dashboard.add
Normal file
1
changelog.d/oban-live_dashboard.add
Normal file
|
@ -0,0 +1 @@
|
|||
Oban jobs can now be viewed in the Live Dashboard
|
1
changelog.d/oban-rich-media-errors.fix
Normal file
1
changelog.d/oban-rich-media-errors.fix
Normal file
|
@ -0,0 +1 @@
|
|||
Prevent Rich Media backfill jobs from retrying in cases where it is likely they will fail again.
|
1
changelog.d/oban-timeouts.change
Normal file
1
changelog.d/oban-timeouts.change
Normal file
|
@ -0,0 +1 @@
|
|||
Ensure all Oban jobs have timeouts defined
|
|
@ -600,9 +600,9 @@
|
|||
web_push: 50,
|
||||
transmogrifier: 20,
|
||||
notifications: 20,
|
||||
background: 5,
|
||||
background: 20,
|
||||
search_indexing: [limit: 10, paused: true],
|
||||
slow: 1
|
||||
slow: 5
|
||||
],
|
||||
plugins: [Oban.Plugins.Pruner],
|
||||
crontab: [
|
||||
|
|
|
@ -154,4 +154,19 @@ This forcibly removes all saved values in the database.
|
|||
|
||||
```sh
|
||||
mix pleroma.config [--force] reset
|
||||
|
||||
```
|
||||
|
||||
## Remove invalid MRF modules from the database
|
||||
|
||||
This forcibly removes any enabled MRF that does not exist and will fix the ability of the instance to start.
|
||||
|
||||
=== "OTP"
|
||||
```sh
|
||||
./bin/pleroma_ctl config fix_mrf_policies
|
||||
```
|
||||
|
||||
=== "From Source"
|
||||
```sh
|
||||
mix pleroma.config fix_mrf_policies
|
||||
```
|
|
@ -205,6 +205,35 @@ def run(["delete", group]) do
|
|||
end
|
||||
end
|
||||
|
||||
# Removes any policies that are not a real module
|
||||
# as they will prevent the server from starting
|
||||
def run(["fix_mrf_policies"]) do
|
||||
check_configdb(fn ->
|
||||
start_pleroma()
|
||||
|
||||
group = :pleroma
|
||||
key = :mrf
|
||||
|
||||
%{value: value} =
|
||||
group
|
||||
|> ConfigDB.get_by_group_and_key(key)
|
||||
|
||||
policies =
|
||||
Keyword.get(value, :policies, [])
|
||||
|> Enum.filter(&is_atom(&1))
|
||||
|> Enum.filter(fn mrf ->
|
||||
case Code.ensure_compiled(mrf) do
|
||||
{:module, _} -> true
|
||||
{:error, _} -> false
|
||||
end
|
||||
end)
|
||||
|
||||
value = Keyword.put(value, :policies, policies)
|
||||
|
||||
ConfigDB.update_or_create(%{group: group, key: key, value: value})
|
||||
end)
|
||||
end
|
||||
|
||||
@spec migrate_to_db(Path.t() | nil) :: any()
|
||||
def migrate_to_db(file_path \\ nil) do
|
||||
with :ok <- Pleroma.Config.DeprecationWarnings.warn() do
|
||||
|
|
|
@ -10,7 +10,7 @@ defmodule Pleroma.Instances.Instance do
|
|||
alias Pleroma.Maps
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Workers.BackgroundWorker
|
||||
alias Pleroma.Workers.DeleteWorker
|
||||
|
||||
use Ecto.Schema
|
||||
|
||||
|
@ -297,7 +297,7 @@ defp scrape_metadata(%URI{} = instance_uri) do
|
|||
all of those users' activities and notifications.
|
||||
"""
|
||||
def delete_users_and_activities(host) when is_binary(host) do
|
||||
BackgroundWorker.enqueue("delete_instance", %{"host" => host})
|
||||
DeleteWorker.enqueue("delete_instance", %{"host" => host})
|
||||
end
|
||||
|
||||
def perform(:delete_instance, host) when is_binary(host) do
|
||||
|
|
|
@ -59,6 +59,7 @@ def refetch_object(%Object{data: %{"id" => id}} = object) do
|
|||
end
|
||||
|
||||
# Note: will create a Create activity, which we need internally at the moment.
|
||||
@spec fetch_object_from_id(String.t(), list()) :: {:ok, Object.t()} | {:error | :reject, any()}
|
||||
def fetch_object_from_id(id, options \\ []) do
|
||||
with {_, nil} <- {:fetch_object, Object.get_cached_by_ap_id(id)},
|
||||
{_, true} <- {:allowed_depth, Federator.allowed_thread_distance?(options[:depth])},
|
||||
|
|
|
@ -40,6 +40,7 @@ defmodule Pleroma.User do
|
|||
alias Pleroma.Web.RelMe
|
||||
alias Pleroma.Webhook.Notify
|
||||
alias Pleroma.Workers.BackgroundWorker
|
||||
alias Pleroma.Workers.DeleteWorker
|
||||
alias Pleroma.Workers.UserRefreshWorker
|
||||
|
||||
require Logger
|
||||
|
@ -2032,7 +2033,7 @@ def delete(users) when is_list(users) do
|
|||
def delete(%User{} = user) do
|
||||
# Purge the user immediately
|
||||
purge(user)
|
||||
BackgroundWorker.enqueue("delete_user", %{"user_id" => user.id})
|
||||
DeleteWorker.enqueue("delete_user", %{"user_id" => user.id})
|
||||
end
|
||||
|
||||
# *Actually* delete the user from the DB
|
||||
|
|
|
@ -540,6 +540,9 @@ def handle_incoming(
|
|||
else
|
||||
_ -> e
|
||||
end
|
||||
|
||||
e ->
|
||||
{:error, e}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
alias Pleroma.Web.ActivityPub.Visibility
|
||||
alias Pleroma.Web.CommonAPI.ActivityDraft
|
||||
|
||||
import Ecto.Query, only: [where: 3]
|
||||
import Pleroma.Web.Gettext
|
||||
import Pleroma.Web.CommonAPI.Utils
|
||||
|
||||
|
@ -156,6 +157,7 @@ def reject_follow_request(follower, followed) do
|
|||
def delete(activity_id, user) do
|
||||
with {_, %Activity{data: %{"object" => _, "type" => "Create"}} = activity} <-
|
||||
{:find_activity, Activity.get_by_id(activity_id, filter: [])},
|
||||
{_, {:ok, _}} <- {:cancel_jobs, maybe_cancel_jobs(activity)},
|
||||
{_, %Object{} = object, _} <-
|
||||
{:find_object, Object.normalize(activity, fetch: false), activity},
|
||||
true <- User.privileged?(user, :messages_delete) || user.ap_id == object.data["actor"],
|
||||
|
@ -223,6 +225,7 @@ def unrepeat(id, user) do
|
|||
{:find_activity, Activity.get_by_id(id)},
|
||||
%Object{} = note <- Object.normalize(activity, fetch: false),
|
||||
%Activity{} = announce <- Utils.get_existing_announce(user.ap_id, note),
|
||||
{_, {:ok, _}} <- {:cancel_jobs, maybe_cancel_jobs(announce)},
|
||||
{:ok, undo, _} <- Builder.undo(user, announce),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(undo, local: true) do
|
||||
{:ok, activity}
|
||||
|
@ -275,6 +278,7 @@ def unfavorite(id, user) do
|
|||
{:find_activity, Activity.get_by_id(id)},
|
||||
%Object{} = note <- Object.normalize(activity, fetch: false),
|
||||
%Activity{} = like <- Utils.get_existing_like(user.ap_id, note),
|
||||
{_, {:ok, _}} <- {:cancel_jobs, maybe_cancel_jobs(like)},
|
||||
{:ok, undo, _} <- Builder.undo(user, like),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(undo, local: true) do
|
||||
{:ok, activity}
|
||||
|
@ -298,6 +302,7 @@ def react_with_emoji(id, user, emoji) do
|
|||
|
||||
def unreact_with_emoji(id, user, emoji) do
|
||||
with %Activity{} = reaction_activity <- Utils.get_latest_reaction(id, user, emoji),
|
||||
{_, {:ok, _}} <- {:cancel_jobs, maybe_cancel_jobs(reaction_activity)},
|
||||
{:ok, undo, _} <- Builder.undo(user, reaction_activity),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(undo, local: true) do
|
||||
{:ok, activity}
|
||||
|
@ -807,4 +812,14 @@ defp make_update_event_data(user, orig_object, changes, location) do
|
|||
_ -> {:error, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_cancel_jobs(%Activity{data: %{"id" => ap_id}}) do
|
||||
Oban.Job
|
||||
|> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
|
||||
|> where([j], j.args["op"] == "publish_one")
|
||||
|> where([j], j.args["params"]["id"] == ^ap_id)
|
||||
|> Oban.cancel_all_jobs()
|
||||
end
|
||||
|
||||
defp maybe_cancel_jobs(_), do: {:ok, 0}
|
||||
end
|
||||
|
|
|
@ -25,11 +25,14 @@ def scrub_html_and_truncate(%{data: %{"summary" => summary}} = object)
|
|||
|> scrub_html_and_truncate_object_field(object)
|
||||
end
|
||||
|
||||
def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do
|
||||
def scrub_html_and_truncate(%{data: %{"content" => content}} = object)
|
||||
when is_binary(content) and content != "" do
|
||||
content
|
||||
|> scrub_html_and_truncate_object_field(object)
|
||||
end
|
||||
|
||||
def scrub_html_and_truncate(%{}), do: ""
|
||||
|
||||
def scrub_html_and_truncate(content, max_length \\ 200, omission \\ "...")
|
||||
when is_binary(content) do
|
||||
content
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.RichMedia.Backfill do
|
||||
alias Pleroma.Web.RichMedia.Card
|
||||
alias Pleroma.Web.RichMedia.Helpers
|
||||
alias Pleroma.Web.RichMedia.Parser
|
||||
alias Pleroma.Web.RichMedia.Parser.TTL
|
||||
alias Pleroma.Workers.RichMediaWorker
|
||||
|
@ -16,8 +17,7 @@ defmodule Pleroma.Web.RichMedia.Backfill do
|
|||
Pleroma.Web.ActivityPub.ActivityPub
|
||||
)
|
||||
|
||||
@spec run(map()) ::
|
||||
:ok | {:error, {:invalid_metadata, any()} | :body_too_large | {:content, any()} | any()}
|
||||
@spec run(map()) :: :ok | Parser.parse_errors() | Helpers.get_errors()
|
||||
def run(%{"url" => url} = args) do
|
||||
url_hash = Card.url_to_hash(url)
|
||||
|
||||
|
@ -33,22 +33,16 @@ def run(%{"url" => url} = args) do
|
|||
end
|
||||
|
||||
warm_cache(url_hash, card)
|
||||
:ok
|
||||
|
||||
{:error, {:invalid_metadata, fields}} ->
|
||||
Logger.debug("Rich media incomplete or invalid metadata for #{url}: #{inspect(fields)}")
|
||||
{:error, type} = error
|
||||
when type in [:invalid_metadata, :body_too_large, :content_type, :validate] ->
|
||||
negative_cache(url_hash)
|
||||
error
|
||||
|
||||
{:error, :body_too_large} ->
|
||||
Logger.error("Rich media error for #{url}: :body_too_large")
|
||||
negative_cache(url_hash)
|
||||
|
||||
{:error, {:content_type, type}} ->
|
||||
Logger.debug("Rich media error for #{url}: :content_type is #{type}")
|
||||
negative_cache(url_hash)
|
||||
|
||||
e ->
|
||||
Logger.debug("Rich media error for #{url}: #{inspect(e)}")
|
||||
{:error, e}
|
||||
{:error, type} = error
|
||||
when type in [:get, :head] ->
|
||||
error
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
defmodule Pleroma.Web.RichMedia.Helpers do
|
||||
alias Pleroma.Config
|
||||
|
||||
require Logger
|
||||
|
||||
@type get_errors :: {:error, :body_too_large | :content_type | :head | :get}
|
||||
|
||||
@spec rich_media_get(String.t()) :: {:ok, String.t()} | get_errors()
|
||||
|
||||
defp headers do
|
||||
user_agent =
|
||||
case Pleroma.Config.get([:rich_media, :user_agent], :default) do
|
||||
|
@ -21,23 +27,30 @@ defp headers do
|
|||
def rich_media_get(url) do
|
||||
headers = headers()
|
||||
|
||||
head_check =
|
||||
case Pleroma.HTTP.head(url, headers, http_options()) do
|
||||
# If the HEAD request didn't reach the server for whatever reason,
|
||||
# we assume the GET that comes right after won't either
|
||||
{:error, _} = e ->
|
||||
e
|
||||
with {_, {:ok, %Tesla.Env{status: 200, headers: headers}}} <-
|
||||
{:head, Pleroma.HTTP.head(url, headers, http_options())},
|
||||
{_, :ok} <- {:content_type, check_content_type(headers)},
|
||||
{_, :ok} <- {:content_length, check_content_length(headers)},
|
||||
{_, {:ok, %Tesla.Env{status: 200, body: body}}} <-
|
||||
{:get, Pleroma.HTTP.get(url, headers, http_options())} do
|
||||
{:ok, body}
|
||||
else
|
||||
{:head, _} ->
|
||||
Logger.debug("Rich media error for #{url}: HTTP HEAD failed")
|
||||
{:error, :head}
|
||||
|
||||
{:ok, %Tesla.Env{status: 200, headers: headers}} ->
|
||||
with :ok <- check_content_type(headers),
|
||||
:ok <- check_content_length(headers),
|
||||
do: :ok
|
||||
{:content_type, {_, type}} ->
|
||||
Logger.debug("Rich media error for #{url}: content-type is #{type}")
|
||||
{:error, :content_type}
|
||||
|
||||
_ ->
|
||||
:ok
|
||||
end
|
||||
{:content_length, {_, length}} ->
|
||||
Logger.debug("Rich media error for #{url}: content-length is #{length}")
|
||||
{:error, :body_too_large}
|
||||
|
||||
with :ok <- head_check, do: Pleroma.HTTP.get(url, headers, http_options())
|
||||
{:get, _} ->
|
||||
Logger.debug("Rich media error for #{url}: HTTP GET failed")
|
||||
{:error, :get}
|
||||
end
|
||||
end
|
||||
|
||||
defp check_content_type(headers) do
|
||||
|
@ -45,7 +58,7 @@ defp check_content_type(headers) do
|
|||
{_, content_type} ->
|
||||
case Plug.Conn.Utils.media_type(content_type) do
|
||||
{:ok, "text", "html", _} -> :ok
|
||||
_ -> {:error, {:content_type, content_type}}
|
||||
_ -> {:error, content_type}
|
||||
end
|
||||
|
||||
_ ->
|
||||
|
@ -60,7 +73,7 @@ defp check_content_length(headers) do
|
|||
{_, maybe_content_length} ->
|
||||
case Integer.parse(maybe_content_length) do
|
||||
{content_length, ""} when content_length <= max_body -> :ok
|
||||
{_, ""} -> {:error, :body_too_large}
|
||||
{_, ""} -> {:error, maybe_content_length}
|
||||
_ -> :ok
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.RichMedia.Parser do
|
||||
alias Pleroma.Web.RichMedia.Helpers
|
||||
require Logger
|
||||
|
||||
@config_impl Application.compile_env(:pleroma, [__MODULE__, :config_impl], Pleroma.Config)
|
||||
|
@ -11,24 +12,26 @@ defp parsers do
|
|||
Pleroma.Config.get([:rich_media, :parsers])
|
||||
end
|
||||
|
||||
def parse(nil), do: nil
|
||||
@type parse_errors :: {:error, :rich_media_disabled | :validate}
|
||||
|
||||
@spec parse(String.t()) :: {:ok, map()} | {:error, any()}
|
||||
def parse(url) do
|
||||
@spec parse(String.t()) ::
|
||||
{:ok, map()} | parse_errors() | Helpers.get_errors()
|
||||
def parse(url) when is_binary(url) do
|
||||
with {_, true} <- {:config, @config_impl.get([:rich_media, :enabled])},
|
||||
:ok <- validate_page_url(url),
|
||||
{:ok, data} <- parse_url(url) do
|
||||
{_, :ok} <- {:validate, validate_page_url(url)},
|
||||
{_, {:ok, data}} <- {:parse, parse_url(url)} do
|
||||
data = Map.put(data, "url", url)
|
||||
{:ok, data}
|
||||
else
|
||||
{:config, _} -> {:error, :rich_media_disabled}
|
||||
e -> e
|
||||
{:validate, _} -> {:error, :validate}
|
||||
{:parse, error} -> error
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_url(url) do
|
||||
with {:ok, %Tesla.Env{body: html}} <- Pleroma.Web.RichMedia.Helpers.rich_media_get(url),
|
||||
{:ok, html} <- Floki.parse_document(html) do
|
||||
with {:ok, body} <- Helpers.rich_media_get(url),
|
||||
{:ok, html} <- Floki.parse_document(body) do
|
||||
html
|
||||
|> maybe_parse()
|
||||
|> clean_parsed_data()
|
||||
|
@ -50,8 +53,8 @@ defp check_parsed_data(%{"title" => title} = data)
|
|||
{:ok, data}
|
||||
end
|
||||
|
||||
defp check_parsed_data(data) do
|
||||
{:error, {:invalid_metadata, data}}
|
||||
defp check_parsed_data(_data) do
|
||||
{:error, :invalid_metadata}
|
||||
end
|
||||
|
||||
defp clean_parsed_data(data) do
|
||||
|
|
|
@ -22,7 +22,7 @@ defp get_oembed_url([{"link", attributes, _children} | _]) do
|
|||
end
|
||||
|
||||
defp get_oembed_data(url) do
|
||||
with {:ok, %Tesla.Env{body: json}} <- Pleroma.Web.RichMedia.Helpers.rich_media_get(url) do
|
||||
with {:ok, json} <- Pleroma.Web.RichMedia.Helpers.rich_media_get(url) do
|
||||
Jason.decode(json)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1137,7 +1137,7 @@ defmodule Pleroma.Web.Router do
|
|||
|
||||
scope "/" do
|
||||
pipe_through([:pleroma_html, :authenticate, :require_admin])
|
||||
live_dashboard("/phoenix/live_dashboard")
|
||||
live_dashboard("/phoenix/live_dashboard", additional_pages: [oban: Oban.LiveDashboard])
|
||||
end
|
||||
|
||||
# Test-only routes needed to test action dispatching and plug chain execution
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Workers.BackgroundWorker do
|
||||
alias Pleroma.Instances.Instance
|
||||
alias Pleroma.User
|
||||
|
||||
use Pleroma.Workers.WorkerHelper, queue: "background"
|
||||
|
@ -15,11 +14,6 @@ def perform(%Job{args: %{"op" => "user_activation", "user_id" => user_id, "statu
|
|||
User.perform(:set_activation_async, user, status)
|
||||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "delete_user", "user_id" => user_id}}) do
|
||||
user = User.get_cached_by_id(user_id)
|
||||
User.perform(:delete, user)
|
||||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "force_password_reset", "user_id" => user_id}}) do
|
||||
user = User.get_cached_by_id(user_id)
|
||||
User.perform(:force_password_reset, user)
|
||||
|
@ -45,10 +39,6 @@ def perform(%Job{args: %{"op" => "verify_fields_links", "user_id" => user_id}})
|
|||
User.perform(:verify_fields_links, user)
|
||||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "delete_instance", "host" => host}}) do
|
||||
Instance.perform(:delete_instance, host)
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(900)
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
end
|
||||
|
|
|
@ -58,4 +58,7 @@ def send_email(user) do
|
|||
|
||||
User.touch_last_digest_emailed_at(user)
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
end
|
||||
|
|
|
@ -60,4 +60,7 @@ def perform(_job) do
|
|||
|
||||
:ok
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
end
|
||||
|
|
24
lib/pleroma/workers/delete_worker.ex
Normal file
24
lib/pleroma/workers/delete_worker.ex
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Workers.DeleteWorker do
|
||||
alias Pleroma.Instances.Instance
|
||||
alias Pleroma.User
|
||||
|
||||
use Pleroma.Workers.WorkerHelper, queue: "slow"
|
||||
|
||||
@impl Oban.Worker
|
||||
|
||||
def perform(%Job{args: %{"op" => "delete_user", "user_id" => user_id}}) do
|
||||
user = User.get_cached_by_id(user_id)
|
||||
User.perform(:delete, user)
|
||||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "delete_instance", "host" => host}}) do
|
||||
Instance.perform(:delete_instance, host)
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(900)
|
||||
end
|
|
@ -6,8 +6,8 @@ defmodule Pleroma.Workers.PurgeExpiredActivity do
|
|||
@moduledoc """
|
||||
Worker which purges expired activity.
|
||||
"""
|
||||
|
||||
use Oban.Worker, queue: :slow, max_attempts: 1, unique: [period: :infinity]
|
||||
@queue :background
|
||||
use Oban.Worker, queue: @queue, max_attempts: 1, unique: [period: :infinity]
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -46,20 +46,22 @@ defp enabled? do
|
|||
|
||||
defp find_activity(id) do
|
||||
with nil <- Activity.get_by_id_with_object(id) do
|
||||
{:error, :activity_not_found}
|
||||
{:cancel, :activity_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
defp find_user(ap_id) do
|
||||
with nil <- Pleroma.User.get_by_ap_id(ap_id) do
|
||||
{:error, :user_not_found}
|
||||
{:cancel, :user_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def get_expiration(id) do
|
||||
queue = Atom.to_string(@queue)
|
||||
|
||||
from(j in Oban.Job,
|
||||
where: j.state == "scheduled",
|
||||
where: j.queue == "slow",
|
||||
where: j.queue == ^queue,
|
||||
where: fragment("?->>'activity_id' = ?", j.args, ^id)
|
||||
)
|
||||
|> Pleroma.Repo.one()
|
||||
|
|
|
@ -13,7 +13,7 @@ def perform(%Job{args: %{"op" => "fetch_remote", "id" => id} = args}) do
|
|||
{:ok, _object} ->
|
||||
:ok
|
||||
|
||||
{:rejected, reason} ->
|
||||
{:reject, reason} ->
|
||||
{:cancel, reason}
|
||||
|
||||
{:error, :forbidden} ->
|
||||
|
@ -27,9 +27,6 @@ def perform(%Job{args: %{"op" => "fetch_remote", "id" => id} = args}) do
|
|||
|
||||
{:error, _} = e ->
|
||||
e
|
||||
|
||||
e ->
|
||||
{:error, e}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -14,6 +14,23 @@ def perform(%Job{args: %{"op" => "expire", "url" => url} = _args}) do
|
|||
end
|
||||
|
||||
def perform(%Job{args: %{"op" => "backfill", "url" => _url} = args}) do
|
||||
Backfill.run(args)
|
||||
case Backfill.run(args) do
|
||||
:ok ->
|
||||
:ok
|
||||
|
||||
{:error, type}
|
||||
when type in [:invalid_metadata, :body_too_large, :content_type, :validate] ->
|
||||
{:cancel, type}
|
||||
|
||||
{:error, type}
|
||||
when type in [:get, :head] ->
|
||||
{:error, type}
|
||||
|
||||
error ->
|
||||
{:error, error}
|
||||
end
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
end
|
||||
|
|
|
@ -20,4 +20,7 @@ def perform(%Job{args: %{"op" => "remove_from_index", "object" => object_id}}) d
|
|||
|
||||
search_module.remove_from_index(object)
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
end
|
||||
|
|
|
@ -11,4 +11,7 @@ defmodule Pleroma.Workers.UserRefreshWorker do
|
|||
def perform(%Job{args: %{"ap_id" => ap_id}}) do
|
||||
User.fetch_by_ap_id(ap_id)
|
||||
end
|
||||
|
||||
@impl Oban.Worker
|
||||
def timeout(_job), do: :timer.seconds(5)
|
||||
end
|
||||
|
|
1
mix.exs
1
mix.exs
|
@ -204,6 +204,7 @@ defp deps do
|
|||
{:exile, "~> 0.10.0"},
|
||||
{:bandit, "~> 1.5.2"},
|
||||
{:websock_adapter, "~> 0.5.6"},
|
||||
{:oban_live_dashboard, "~> 0.1.1"},
|
||||
{:icalendar, "~> 1.1"},
|
||||
{:geospatial, "~> 0.3.0"},
|
||||
|
||||
|
|
9
mix.lock
9
mix.lock
|
@ -27,7 +27,7 @@
|
|||
"crypt": {:git, "https://github.com/msantos/crypt.git", "f75cd55325e33cbea198fb41fe41871392f8fb76", [ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"]},
|
||||
"csv": {:hex, :csv, "2.4.1", "50e32749953b6bf9818dbfed81cf1190e38cdf24f95891303108087486c5925e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm", "54508938ac67e27966b10ef49606e3ad5995d665d7fc2688efb3eab1307c9079"},
|
||||
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
|
||||
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
|
||||
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
|
||||
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
||||
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"},
|
||||
|
@ -37,7 +37,7 @@
|
|||
"ecto": {:hex, :ecto, "3.11.2", "e1d26be989db350a633667c5cda9c3d115ae779b66da567c68c80cfb26a8c9ee", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c38bca2c6f8d8023f2145326cc8a80100c3ffe4dcbd9842ff867f7fc6156c65"},
|
||||
"ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
|
||||
"ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.15", "0fc29dbae0e444a29bd6abeee4cf3c4c037e692a272478a234a1cc765077dbb1", [:mix], [{:ecto_sql, "~> 3.7", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1 or ~> 4.0.0", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "b6127f3a5c6fc3d84895e4768cc7c199f22b48b67d6c99b13fbf4a374e73f039"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.11.2", "c7cc7f812af571e50b80294dc2e535821b3b795ce8008d07aa5f336591a185a8", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "73c07f995ac17dbf89d3cfaaf688fcefabcd18b7b004ac63b0dc4ef39499ed6b"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.11.3", "4eb7348ff8101fbc4e6bbc5a4404a24fecbe73a3372d16569526b0cf34ebc195", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e5f36e3d736b99c7fee3e631333b8394ade4bafe9d96d35669fca2d81c2be928"},
|
||||
"eimp": {:hex, :eimp, "1.0.14", "fc297f0c7e2700457a95a60c7010a5f1dcb768a083b6d53f49cd94ab95a28f22", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "501133f3112079b92d9e22da8b88bf4f0e13d4d67ae9c15c42c30bd25ceb83b6"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.7.8", "505026f266552ee5aabca0b9f9c229cbb496c689537c9f922f3eb5431157efc7", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.0", [hex: :certifi, repo: "hexpm", optional: true]}], "hexpm", "7a71945b913d37ea89b06966e1342c85cfe549b15e6d6d081e8081c493062c07"},
|
||||
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||
|
@ -73,7 +73,7 @@
|
|||
"icalendar": {:hex, :icalendar, "1.1.2", "5d0afff5d0143c5bd43f18ae32a777bf0fb9a724543ab05229a460d368f0a5e7", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "2060f8e353fdf3047e95a3f012583dc3c0bbd7ca1010e32ed9e9fc5760ad4292"},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"inet_cidr": {:hex, :inet_cidr, "1.0.8", "d26bb7bdbdf21ae401ead2092bf2bb4bf57fe44a62f5eaa5025280720ace8a40", [:mix], [], "hexpm", "d5b26da66603bb56c933c65214c72152f0de9a6ea53618b56d63302a68f6a90e"},
|
||||
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
||||
"jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"},
|
||||
"joken": {:hex, :joken, "2.6.0", "b9dd9b6d52e3e6fcb6c65e151ad38bf4bc286382b5b6f97079c47ade6b1bcc6a", [:mix], [{:jose, "~> 1.11.5", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "5a95b05a71cd0b54abd35378aeb1d487a23a52c324fa7efdffc512b655b5aaa7"},
|
||||
"jose": {:hex, :jose, "1.11.6", "613fda82552128aa6fb804682e3a616f4bc15565a048dabd05b1ebd5827ed965", [:mix, :rebar3], [], "hexpm", "6275cb75504f9c1e60eeacb771adfeee4905a9e182103aa59b53fed651ff9738"},
|
||||
"jumper": {:hex, :jumper, "1.0.2", "68cdcd84472a00ac596b4e6459a41b3062d4427cbd4f1e8c8793c5b54f1406a7", [:mix], [], "hexpm", "9b7782409021e01ab3c08270e26f36eb62976a38c1aa64b2eaf6348422f165e1"},
|
||||
|
@ -98,7 +98,8 @@
|
|||
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
|
||||
"oauth2": {:hex, :oauth2, "0.9.4", "632e8e8826a45e33ac2ea5ac66dcc019ba6bb5a0d2ba77e342d33e3b7b252c6e", [:mix], [{:hackney, "~> 1.7", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "407c6b9f60aa0d01b915e2347dc6be78adca706a37f0c530808942da3b62e7af"},
|
||||
"oauther": {:hex, :oauther, "1.3.0", "82b399607f0ca9d01c640438b34d74ebd9e4acd716508f868e864537ecdb1f76", [:mix], [], "hexpm", "78eb888ea875c72ca27b0864a6f550bc6ee84f2eeca37b093d3d833fbcaec04e"},
|
||||
"oban": {:hex, :oban, "2.17.10", "c3e5bd739b5c3fdc38eba1d43ab270a8c6ca4463bb779b7705c69400b0d87678", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4afd027b8e2bc3c399b54318b4f46ee8c40251fb55a285cb4e38b5363f0ee7c4"},
|
||||
"oban": {:hex, :oban, "2.17.12", "33fb0cbfb92b910d48dd91a908590fe3698bb85eacec8cd0d9bc6aa13dddd6d6", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7a647d6cd6bb300073db17faabce22d80ae135da3baf3180a064fa7c4fa046e3"},
|
||||
"oban_live_dashboard": {:hex, :oban_live_dashboard, "0.1.1", "8aa4ceaf381c818f7d5c8185cc59942b8ac82ef0cf559881aacf8d3f8ac7bdd3", [:mix], [{:oban, "~> 2.15", [hex: :oban, repo: "hexpm", optional: false]}, {:phoenix_live_dashboard, "~> 0.7", [hex: :phoenix_live_dashboard, repo: "hexpm", optional: false]}], "hexpm", "16dc4ce9c9a95aa2e655e35ed4e675652994a8def61731a18af85e230e1caa63"},
|
||||
"octo_fetch": {:hex, :octo_fetch, "0.4.0", "074b5ecbc08be10b05b27e9db08bc20a3060142769436242702931c418695b19", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "cf8be6f40cd519d7000bb4e84adcf661c32e59369ca2827c4e20042eda7a7fc6"},
|
||||
"open_api_spex": {:hex, :open_api_spex, "3.18.2", "8c855e83bfe8bf81603d919d6e892541eafece3720f34d1700b58024dadde247", [: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 or ~> 4.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "aa3e6dcfc0ad6a02596b2172662da21c9dd848dac145ea9e603f54e3d81b8d2b"},
|
||||
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm", "639b2e8749e11b87b9eb42f2ad325d161c170b39b288ac8d04c4f31f8f0823eb"},
|
||||
|
|
|
@ -13,6 +13,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Rule
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
|
@ -22,7 +23,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Workers.PollWorker
|
||||
|
||||
import Ecto.Query, only: [from: 2]
|
||||
import Ecto.Query, only: [from: 2, where: 3]
|
||||
import Mock
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
@ -1968,4 +1969,217 @@ test "it does not boost if group is blocking poster", %{poster: poster, group: g
|
|||
assert [] = announces
|
||||
end
|
||||
end
|
||||
|
||||
describe "Oban jobs are cancelled" do
|
||||
setup do
|
||||
clear_config([:instance, :federating], true)
|
||||
|
||||
local_user = insert(:user)
|
||||
|
||||
remote_one =
|
||||
insert(:user, %{
|
||||
local: false,
|
||||
nickname: "nick1@domain.com",
|
||||
ap_id: "https://domain.com/users/nick1",
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
shared_inbox: "https://domain.com/inbox"
|
||||
})
|
||||
|
||||
remote_two =
|
||||
insert(:user, %{
|
||||
local: false,
|
||||
nickname: "nick2@example.com",
|
||||
ap_id: "https://example.com/users/nick2",
|
||||
inbox: "https://example.com/users/nick2/inbox",
|
||||
shared_inbox: "https://example.com/inbox"
|
||||
})
|
||||
|
||||
%{local_user: local_user, remote_one: remote_one, remote_two: remote_two}
|
||||
end
|
||||
|
||||
test "when deleting posts", %{
|
||||
local_user: local_user,
|
||||
remote_one: remote_one,
|
||||
remote_two: remote_two
|
||||
} do
|
||||
{:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
|
||||
{:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
|
||||
|
||||
{:ok, %{data: %{"id" => ap_id}} = activity} =
|
||||
CommonAPI.post(local_user, %{status: "Happy Friday everyone!"})
|
||||
|
||||
# Generate the publish_one jobs
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
publish_one_jobs =
|
||||
all_enqueued()
|
||||
|> Enum.filter(fn job ->
|
||||
match?(
|
||||
%{
|
||||
state: "available",
|
||||
queue: "federator_outgoing",
|
||||
worker: "Pleroma.Workers.PublisherWorker",
|
||||
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
|
||||
},
|
||||
job
|
||||
)
|
||||
end)
|
||||
|
||||
assert length(publish_one_jobs) == 2
|
||||
|
||||
# The delete should have triggered cancelling the publish_one jobs
|
||||
assert {:ok, _delete} = CommonAPI.delete(activity.id, local_user)
|
||||
|
||||
# all_enqueued/1 will not return cancelled jobs
|
||||
cancelled_jobs =
|
||||
Oban.Job
|
||||
|> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
|
||||
|> where([j], j.state == "cancelled")
|
||||
|> where([j], j.args["op"] == "publish_one")
|
||||
|> where([j], j.args["params"]["id"] == ^ap_id)
|
||||
|> Pleroma.Repo.all()
|
||||
|
||||
assert length(cancelled_jobs) == 2
|
||||
end
|
||||
|
||||
test "when unfavoriting posts", %{
|
||||
local_user: local_user,
|
||||
remote_one: remote_user
|
||||
} do
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(remote_user, %{status: "I like turtles!"})
|
||||
|
||||
{:ok, %{data: %{"id" => ap_id}} = _favorite} =
|
||||
CommonAPI.favorite(local_user, activity.id)
|
||||
|
||||
# Generate the publish_one jobs
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
publish_one_jobs =
|
||||
all_enqueued()
|
||||
|> Enum.filter(fn job ->
|
||||
match?(
|
||||
%{
|
||||
state: "available",
|
||||
queue: "federator_outgoing",
|
||||
worker: "Pleroma.Workers.PublisherWorker",
|
||||
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
|
||||
},
|
||||
job
|
||||
)
|
||||
end)
|
||||
|
||||
assert length(publish_one_jobs) == 1
|
||||
|
||||
# The unfavorite should have triggered cancelling the publish_one jobs
|
||||
assert {:ok, _unfavorite} = CommonAPI.unfavorite(activity.id, local_user)
|
||||
|
||||
# all_enqueued/1 will not return cancelled jobs
|
||||
cancelled_jobs =
|
||||
Oban.Job
|
||||
|> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
|
||||
|> where([j], j.state == "cancelled")
|
||||
|> where([j], j.args["op"] == "publish_one")
|
||||
|> where([j], j.args["params"]["id"] == ^ap_id)
|
||||
|> Pleroma.Repo.all()
|
||||
|
||||
assert length(cancelled_jobs) == 1
|
||||
end
|
||||
|
||||
test "when unboosting posts", %{
|
||||
local_user: local_user,
|
||||
remote_one: remote_one,
|
||||
remote_two: remote_two
|
||||
} do
|
||||
{:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
|
||||
{:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(remote_one, %{status: "This is an unpleasant post"})
|
||||
|
||||
{:ok, %{data: %{"id" => ap_id}} = _repeat} =
|
||||
CommonAPI.repeat(activity.id, local_user)
|
||||
|
||||
# Generate the publish_one jobs
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
publish_one_jobs =
|
||||
all_enqueued()
|
||||
|> Enum.filter(fn job ->
|
||||
match?(
|
||||
%{
|
||||
state: "available",
|
||||
queue: "federator_outgoing",
|
||||
worker: "Pleroma.Workers.PublisherWorker",
|
||||
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
|
||||
},
|
||||
job
|
||||
)
|
||||
end)
|
||||
|
||||
assert length(publish_one_jobs) == 2
|
||||
|
||||
# The unrepeat should have triggered cancelling the publish_one jobs
|
||||
assert {:ok, _unfavorite} = CommonAPI.unrepeat(activity.id, local_user)
|
||||
|
||||
# all_enqueued/1 will not return cancelled jobs
|
||||
cancelled_jobs =
|
||||
Oban.Job
|
||||
|> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
|
||||
|> where([j], j.state == "cancelled")
|
||||
|> where([j], j.args["op"] == "publish_one")
|
||||
|> where([j], j.args["params"]["id"] == ^ap_id)
|
||||
|> Pleroma.Repo.all()
|
||||
|
||||
assert length(cancelled_jobs) == 2
|
||||
end
|
||||
|
||||
test "when unreacting to posts", %{
|
||||
local_user: local_user,
|
||||
remote_one: remote_one,
|
||||
remote_two: remote_two
|
||||
} do
|
||||
{:ok, _, _} = Pleroma.User.follow(remote_one, local_user)
|
||||
{:ok, _, _} = Pleroma.User.follow(remote_two, local_user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(remote_one, %{status: "Gang gang!!!!"})
|
||||
|
||||
{:ok, %{data: %{"id" => ap_id}} = _react} =
|
||||
CommonAPI.react_with_emoji(activity.id, local_user, "👍")
|
||||
|
||||
# Generate the publish_one jobs
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
publish_one_jobs =
|
||||
all_enqueued()
|
||||
|> Enum.filter(fn job ->
|
||||
match?(
|
||||
%{
|
||||
state: "available",
|
||||
queue: "federator_outgoing",
|
||||
worker: "Pleroma.Workers.PublisherWorker",
|
||||
args: %{"op" => "publish_one", "params" => %{"id" => ^ap_id}}
|
||||
},
|
||||
job
|
||||
)
|
||||
end)
|
||||
|
||||
assert length(publish_one_jobs) == 2
|
||||
|
||||
# The unreact should have triggered cancelling the publish_one jobs
|
||||
assert {:ok, _unreact} = CommonAPI.unreact_with_emoji(activity.id, local_user, "👍")
|
||||
|
||||
# all_enqueued/1 will not return cancelled jobs
|
||||
cancelled_jobs =
|
||||
Oban.Job
|
||||
|> where([j], j.worker == "Pleroma.Workers.PublisherWorker")
|
||||
|> where([j], j.state == "cancelled")
|
||||
|> where([j], j.args["op"] == "publish_one")
|
||||
|> where([j], j.args["params"]["id"] == ^ap_id)
|
||||
|> Pleroma.Repo.all()
|
||||
|
||||
assert length(cancelled_jobs) == 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
|
|||
alias Pleroma.Web.Metadata.Utils
|
||||
|
||||
describe "scrub_html_and_truncate/1" do
|
||||
test "it returns content text without encode HTML if summary is nil" do
|
||||
test "it returns content text without HTML if summary is nil" do
|
||||
user = insert(:user)
|
||||
|
||||
note =
|
||||
|
@ -17,14 +17,14 @@ test "it returns content text without encode HTML if summary is nil" do
|
|||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => nil,
|
||||
"content" => "Pleroma's really cool!"
|
||||
"content" => "Pleroma's really cool!<br>"
|
||||
}
|
||||
})
|
||||
|
||||
assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
|
||||
end
|
||||
|
||||
test "it returns context text without encode HTML if summary is empty" do
|
||||
test "it returns content text without HTML if summary is empty" do
|
||||
user = insert(:user)
|
||||
|
||||
note =
|
||||
|
@ -33,14 +33,14 @@ test "it returns context text without encode HTML if summary is empty" do
|
|||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "Pleroma's really cool!"
|
||||
"content" => "Pleroma's really cool!<br>"
|
||||
}
|
||||
})
|
||||
|
||||
assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
|
||||
end
|
||||
|
||||
test "it returns summary text without encode HTML if summary is filled" do
|
||||
test "it returns summary text without HTML if summary is filled" do
|
||||
user = insert(:user)
|
||||
|
||||
note =
|
||||
|
@ -48,7 +48,7 @@ test "it returns summary text without encode HTML if summary is filled" do
|
|||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "Public service announcement on caffeine consumption",
|
||||
"summary" => "Public service announcement on caffeine consumption<br>",
|
||||
"content" => "cofe"
|
||||
}
|
||||
})
|
||||
|
@ -57,6 +57,22 @@ test "it returns summary text without encode HTML if summary is filled" do
|
|||
"Public service announcement on caffeine consumption"
|
||||
end
|
||||
|
||||
test "it returns empty string if summary and content are absent" do
|
||||
user = insert(:user)
|
||||
|
||||
note =
|
||||
insert(:note, %{
|
||||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"content" => nil,
|
||||
"summary" => nil
|
||||
}
|
||||
})
|
||||
|
||||
assert Utils.scrub_html_and_truncate(note) == ""
|
||||
end
|
||||
|
||||
test "it does not return old content after editing" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ test "returns error when no metadata present" do
|
|||
end
|
||||
|
||||
test "doesn't just add a title" do
|
||||
assert {:error, {:invalid_metadata, _}} = Parser.parse("https://example.com/non-ogp")
|
||||
assert {:error, :invalid_metadata} = Parser.parse("https://example.com/non-ogp")
|
||||
end
|
||||
|
||||
test "parses ogp" do
|
||||
|
@ -96,7 +96,7 @@ test "rejects invalid OGP data" do
|
|||
end
|
||||
|
||||
test "returns error if getting page was not successful" do
|
||||
assert {:error, :overload} = Parser.parse("https://example.com/error")
|
||||
assert {:error, :get} = Parser.parse("https://example.com/error")
|
||||
end
|
||||
|
||||
test "does a HEAD request to check if the body is too large" do
|
||||
|
@ -104,17 +104,17 @@ test "does a HEAD request to check if the body is too large" do
|
|||
end
|
||||
|
||||
test "does a HEAD request to check if the body is html" do
|
||||
assert {:error, {:content_type, _}} = Parser.parse("https://example.com/pdf-file")
|
||||
assert {:error, :content_type} = Parser.parse("https://example.com/pdf-file")
|
||||
end
|
||||
|
||||
test "refuses to crawl incomplete URLs" do
|
||||
url = "example.com/ogp"
|
||||
assert :error == Parser.parse(url)
|
||||
assert {:error, :validate} == Parser.parse(url)
|
||||
end
|
||||
|
||||
test "refuses to crawl malformed URLs" do
|
||||
url = "example.com[]/ogp"
|
||||
assert :error == Parser.parse(url)
|
||||
assert {:error, :validate} == Parser.parse(url)
|
||||
end
|
||||
|
||||
test "refuses to crawl URLs of private network from posts" do
|
||||
|
@ -126,7 +126,7 @@ test "refuses to crawl URLs of private network from posts" do
|
|||
"https://pleroma.local/notice/9kCP7V"
|
||||
]
|
||||
|> Enum.each(fn url ->
|
||||
assert :error == Parser.parse(url)
|
||||
assert {:error, :validate} == Parser.parse(url)
|
||||
end)
|
||||
end
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ test "error if user was not found" do
|
|||
user = Pleroma.User.get_by_ap_id(activity.actor)
|
||||
Pleroma.Repo.delete(user)
|
||||
|
||||
assert {:error, :user_not_found} =
|
||||
assert {:cancel, :user_not_found} =
|
||||
perform_job(Pleroma.Workers.PurgeExpiredActivity, %{activity_id: activity.id})
|
||||
end
|
||||
|
||||
|
@ -53,7 +53,7 @@ test "error if actiivity was not found" do
|
|||
expires_at: DateTime.add(DateTime.utc_now(), 3601)
|
||||
})
|
||||
|
||||
assert {:error, :activity_not_found} =
|
||||
assert {:cancel, :activity_not_found} =
|
||||
perform_job(Pleroma.Workers.PurgeExpiredActivity, %{activity_id: "some_if"})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1782,7 +1782,7 @@ def post(url, query, body, headers) do
|
|||
]
|
||||
|
||||
def head(url, _query, _body, _headers) when url in @rich_media_mocks do
|
||||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end
|
||||
|
||||
def head("https://example.com/pdf-file", _, _, _) do
|
||||
|
|
Loading…
Reference in a new issue