Merge remote-tracking branch 'remotes/origin/develop' into 2168-media-preview-proxy
This commit is contained in:
commit
27e7999a15
263 changed files with 2408 additions and 1169 deletions
|
|
@ -134,13 +134,23 @@ defmodule Mix.Tasks.Pleroma.Database do
|
|||
|
||||
Pleroma.Activity
|
||||
|> join(:left, [a], u in assoc(a, :expiration))
|
||||
|> join(:inner, [a, _u], o in Object,
|
||||
on:
|
||||
fragment(
|
||||
"(?->>'id') = COALESCE((?)->'object'->> 'id', (?)->>'object')",
|
||||
o.data,
|
||||
a.data,
|
||||
a.data
|
||||
)
|
||||
)
|
||||
|> where(local: true)
|
||||
|> where([a, u], is_nil(u))
|
||||
|> where([a], fragment("(? ->> 'type'::text) = 'Create'", a.data))
|
||||
|> where([_a, _u, o], fragment("?->>'type' = 'Note'", o.data))
|
||||
|> Pleroma.RepoStreamer.chunk_stream(100)
|
||||
|> Stream.each(fn activities ->
|
||||
Enum.each(activities, fn activity ->
|
||||
expires_at = Timex.shift(activity.inserted_at, days: days)
|
||||
|
||||
Pleroma.ActivityExpiration.create(activity, expires_at, false)
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ defmodule Mix.Tasks.Pleroma.Ecto.Migrate do
|
|||
load_pleroma()
|
||||
{opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
|
||||
|
||||
if Application.get_env(:pleroma, Pleroma.Repo)[:ssl] do
|
||||
Application.ensure_all_started(:ssl)
|
||||
end
|
||||
|
||||
opts =
|
||||
if opts[:to] || opts[:step] || opts[:all],
|
||||
do: opts,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ defmodule Mix.Tasks.Pleroma.Ecto.Rollback do
|
|||
load_pleroma()
|
||||
{opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
|
||||
|
||||
if Application.get_env(:pleroma, Pleroma.Repo)[:ssl] do
|
||||
Application.ensure_all_started(:ssl)
|
||||
end
|
||||
|
||||
opts =
|
||||
if opts[:to] || opts[:step] || opts[:all],
|
||||
do: opts,
|
||||
|
|
|
|||
|
|
@ -340,4 +340,10 @@ defmodule Pleroma.Activity do
|
|||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
@spec pinned_by_actor?(Activity.t()) :: boolean()
|
||||
def pinned_by_actor?(%Activity{} = activity) do
|
||||
actor = user_actor(activity)
|
||||
activity.id in actor.pinned_activities
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,7 +46,12 @@ defmodule Pleroma.ActivityExpiration do
|
|||
|
||||
ActivityExpiration
|
||||
|> where([exp], exp.scheduled_at < ^naive_datetime)
|
||||
|> limit(50)
|
||||
|> preload(:activity)
|
||||
|> Repo.all()
|
||||
|> Enum.reject(fn %{activity: activity} ->
|
||||
Activity.pinned_by_actor?(activity)
|
||||
end)
|
||||
end
|
||||
|
||||
def validate_scheduled_at(changeset, false), do: changeset
|
||||
|
|
|
|||
|
|
@ -81,6 +81,16 @@ defmodule Pleroma.Config do
|
|||
Application.delete_env(:pleroma, key)
|
||||
end
|
||||
|
||||
def restrict_unauthenticated_access?(resource, kind) do
|
||||
setting = get([:restrict_unauthenticated, resource, kind])
|
||||
|
||||
if setting in [nil, :if_instance_is_private] do
|
||||
!get!([:instance, :public])
|
||||
else
|
||||
setting
|
||||
end
|
||||
end
|
||||
|
||||
def oauth_consumer_strategies, do: get([:auth, :oauth_consumer_strategies], [])
|
||||
|
||||
def oauth_consumer_enabled?, do: oauth_consumer_strategies() != []
|
||||
|
|
|
|||
|
|
@ -125,8 +125,8 @@ defmodule Pleroma.Object.Fetcher do
|
|||
defp prepare_activity_params(data) do
|
||||
%{
|
||||
"type" => "Create",
|
||||
"to" => data["to"],
|
||||
"cc" => data["cc"],
|
||||
"to" => data["to"] || [],
|
||||
"cc" => data["cc"] || [],
|
||||
# Should we seriously keep this attributedTo thing?
|
||||
"actor" => data["actor"] || data["attributedTo"],
|
||||
"object" => data
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ defmodule Pleroma.Upload.Filter.Mogrifun do
|
|||
@behaviour Pleroma.Upload.Filter
|
||||
alias Pleroma.Upload.Filter
|
||||
|
||||
@moduledoc """
|
||||
This module is just an example of an Upload filter. It's not supposed to be used in production.
|
||||
"""
|
||||
|
||||
@filters [
|
||||
{"implode", "1"},
|
||||
{"-raise", "20"},
|
||||
|
|
|
|||
|
|
@ -311,10 +311,12 @@ defmodule Pleroma.User do
|
|||
|
||||
def visible_for(_, _), do: :invisible
|
||||
|
||||
defp restrict_unauthenticated?(%User{local: local}) do
|
||||
config_key = if local, do: :local, else: :remote
|
||||
defp restrict_unauthenticated?(%User{local: true}) do
|
||||
Config.restrict_unauthenticated_access?(:profiles, :local)
|
||||
end
|
||||
|
||||
Config.get([:restrict_unauthenticated, :profiles, config_key], false)
|
||||
defp restrict_unauthenticated?(%User{local: _}) do
|
||||
Config.restrict_unauthenticated_access?(:profiles, :remote)
|
||||
end
|
||||
|
||||
defp visible_account_status(user) do
|
||||
|
|
@ -1581,6 +1583,49 @@ defmodule Pleroma.User do
|
|||
|> update_and_set_cache()
|
||||
end
|
||||
|
||||
@spec purge_user_changeset(User.t()) :: Changeset.t()
|
||||
def purge_user_changeset(user) do
|
||||
# "Right to be forgotten"
|
||||
# https://gdpr.eu/right-to-be-forgotten/
|
||||
change(user, %{
|
||||
bio: nil,
|
||||
raw_bio: nil,
|
||||
email: nil,
|
||||
name: nil,
|
||||
password_hash: nil,
|
||||
keys: nil,
|
||||
public_key: nil,
|
||||
avatar: %{},
|
||||
tags: [],
|
||||
last_refreshed_at: nil,
|
||||
last_digest_emailed_at: nil,
|
||||
banner: %{},
|
||||
background: %{},
|
||||
note_count: 0,
|
||||
follower_count: 0,
|
||||
following_count: 0,
|
||||
locked: false,
|
||||
confirmation_pending: false,
|
||||
password_reset_pending: false,
|
||||
approval_pending: false,
|
||||
registration_reason: nil,
|
||||
confirmation_token: nil,
|
||||
domain_blocks: [],
|
||||
deactivated: true,
|
||||
ap_enabled: false,
|
||||
is_moderator: false,
|
||||
is_admin: false,
|
||||
mastofe_settings: nil,
|
||||
mascot: nil,
|
||||
emoji: %{},
|
||||
pleroma_settings_store: %{},
|
||||
fields: [],
|
||||
raw_fields: [],
|
||||
discoverable: false,
|
||||
also_known_as: []
|
||||
})
|
||||
end
|
||||
|
||||
def delete(users) when is_list(users) do
|
||||
for user <- users, do: delete(user)
|
||||
end
|
||||
|
|
@ -1608,7 +1653,7 @@ defmodule Pleroma.User do
|
|||
|
||||
_ ->
|
||||
user
|
||||
|> change(%{deactivated: true, email: nil})
|
||||
|> purge_user_changeset()
|
||||
|> update_and_set_cache()
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -285,32 +285,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
end
|
||||
end
|
||||
|
||||
@spec accept(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def accept(params) do
|
||||
accept_or_reject("Accept", params)
|
||||
end
|
||||
|
||||
@spec reject(map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def reject(params) do
|
||||
accept_or_reject("Reject", params)
|
||||
end
|
||||
|
||||
@spec accept_or_reject(String.t(), map()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
defp accept_or_reject(type, %{to: to, actor: actor, object: object} = params) do
|
||||
local = Map.get(params, :local, true)
|
||||
activity_id = Map.get(params, :activity_id, nil)
|
||||
|
||||
data =
|
||||
%{"to" => to, "type" => type, "actor" => actor.ap_id, "object" => object}
|
||||
|> Maps.put_if_present("id", activity_id)
|
||||
|
||||
with {:ok, activity} <- insert(data, local),
|
||||
_ <- notify_and_stream(activity),
|
||||
:ok <- maybe_federate(activity) do
|
||||
{:ok, activity}
|
||||
end
|
||||
end
|
||||
|
||||
@spec unfollow(User.t(), User.t(), String.t() | nil, boolean()) ::
|
||||
{:ok, Activity.t()} | nil | {:error, any()}
|
||||
def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
|
||||
|
|
|
|||
|
|
@ -14,6 +14,28 @@ defmodule Pleroma.Web.ActivityPub.Builder do
|
|||
|
||||
require Pleroma.Constants
|
||||
|
||||
def accept_or_reject(actor, activity, type) do
|
||||
data = %{
|
||||
"id" => Utils.generate_activity_id(),
|
||||
"actor" => actor.ap_id,
|
||||
"type" => type,
|
||||
"object" => activity.data["id"],
|
||||
"to" => [activity.actor]
|
||||
}
|
||||
|
||||
{:ok, data, []}
|
||||
end
|
||||
|
||||
@spec reject(User.t(), Activity.t()) :: {:ok, map(), keyword()}
|
||||
def reject(actor, rejected_activity) do
|
||||
accept_or_reject(actor, rejected_activity, "Reject")
|
||||
end
|
||||
|
||||
@spec accept(User.t(), Activity.t()) :: {:ok, map(), keyword()}
|
||||
def accept(actor, accepted_activity) do
|
||||
accept_or_reject(actor, accepted_activity, "Accept")
|
||||
end
|
||||
|
||||
@spec follow(User.t(), User.t()) :: {:ok, map(), keyword()}
|
||||
def follow(follower, followed) do
|
||||
data = %{
|
||||
|
|
|
|||
|
|
@ -13,8 +13,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator
|
||||
|
|
@ -30,6 +32,17 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
@spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
|
||||
def validate(object, meta)
|
||||
|
||||
def validate(%{"type" => type} = object, meta)
|
||||
when type in ~w[Accept Reject] do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|> AcceptRejectValidator.cast_and_validate()
|
||||
|> Ecto.Changeset.apply_action(:insert) do
|
||||
object = stringify_keys(object)
|
||||
{:ok, object, meta}
|
||||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => "Follow"} = object, meta) do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|
|
@ -125,6 +138,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => "Audio"} = object, meta) do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|> AudioValidator.cast_and_validate()
|
||||
|> Ecto.Changeset.apply_action(:insert) do
|
||||
object = stringify_keys(object)
|
||||
{:ok, object, meta}
|
||||
end
|
||||
end
|
||||
|
||||
def validate(%{"type" => "Answer"} = object, meta) do
|
||||
with {:ok, object} <-
|
||||
object
|
||||
|
|
@ -164,7 +187,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
%{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity,
|
||||
meta
|
||||
)
|
||||
when objtype in ["Question", "Answer"] do
|
||||
when objtype in ~w[Question Answer Audio] do
|
||||
with {:ok, object_data} <- cast_and_apply(object),
|
||||
meta = Keyword.put(meta, :object_data, object_data |> stringify_keys),
|
||||
{:ok, create_activity} <-
|
||||
|
|
@ -198,6 +221,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
|||
AnswerValidator.cast_and_apply(object)
|
||||
end
|
||||
|
||||
def cast_and_apply(%{"type" => "Audio"} = object) do
|
||||
AudioValidator.cast_and_apply(object)
|
||||
end
|
||||
|
||||
def cast_and_apply(o), do: {:error, {:validator_not_set, o}}
|
||||
|
||||
# is_struct/1 isn't present in Elixir 1.8.x
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
|
||||
import Ecto.Changeset
|
||||
import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
|
||||
@primary_key false
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
%__MODULE__{}
|
||||
|> cast(data, __schema__(:fields))
|
||||
end
|
||||
|
||||
def validate_data(cng) do
|
||||
cng
|
||||
|> validate_required([:id, :type, :actor, :to, :cc, :object])
|
||||
|> validate_inclusion(:type, ["Accept", "Reject"])
|
||||
|> validate_actor_presence()
|
||||
|> validate_object_presence(allowed_types: ["Follow"])
|
||||
|> validate_accept_reject_rights()
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
data
|
||||
|> cast_data
|
||||
|> validate_data
|
||||
end
|
||||
|
||||
def validate_accept_reject_rights(cng) do
|
||||
with object_id when is_binary(object_id) <- get_field(cng, :object),
|
||||
%Activity{data: %{"object" => followed_actor}} <- Activity.get_by_ap_id(object_id),
|
||||
true <- followed_actor == get_field(cng, :actor) do
|
||||
cng
|
||||
else
|
||||
_e ->
|
||||
cng
|
||||
|> add_error(:actor, "can't accept or reject the given activity")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -15,16 +15,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do
|
|||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, {:array, :string}, default: [])
|
||||
field(:cc, {:array, :string}, default: [])
|
||||
|
||||
# is this actually needed?
|
||||
field(:bto, {:array, :string}, default: [])
|
||||
field(:bcc, {:array, :string}, default: [])
|
||||
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
field(:type, :string)
|
||||
field(:name, :string)
|
||||
field(:inReplyTo, :string)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
|
||||
# TODO: Remove actor on objects
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
|
||||
use Ecto.Schema
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
@primary_key false
|
||||
@derive Jason.Encoder
|
||||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
# TODO: Write type
|
||||
field(:tag, {:array, :map}, default: [])
|
||||
field(:type, :string)
|
||||
field(:content, :string)
|
||||
field(:context, :string)
|
||||
|
||||
# TODO: Remove actor on objects
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
|
||||
field(:attributedTo, ObjectValidators.ObjectID)
|
||||
field(:summary, :string)
|
||||
field(:published, ObjectValidators.DateTime)
|
||||
# TODO: Write type
|
||||
field(:emoji, :map, default: %{})
|
||||
field(:sensitive, :boolean, default: false)
|
||||
embeds_many(:attachment, AttachmentValidator)
|
||||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, :string)
|
||||
field(:uri, ObjectValidators.Uri)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
||||
field(:likes, {:array, :string}, default: [])
|
||||
field(:announcements, {:array, :string}, default: [])
|
||||
end
|
||||
|
||||
def cast_and_apply(data) do
|
||||
data
|
||||
|> cast_data
|
||||
|> apply_action(:insert)
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
data
|
||||
|> cast_data()
|
||||
|> validate_data()
|
||||
end
|
||||
|
||||
def cast_data(data) do
|
||||
%__MODULE__{}
|
||||
|> changeset(data)
|
||||
end
|
||||
|
||||
defp fix(data) do
|
||||
data
|
||||
|> CommonFixes.fix_defaults()
|
||||
|> CommonFixes.fix_attribution()
|
||||
end
|
||||
|
||||
def changeset(struct, data) do
|
||||
data = fix(data)
|
||||
|
||||
struct
|
||||
|> cast(data, __schema__(:fields) -- [:attachment])
|
||||
|> cast_embed(:attachment)
|
||||
end
|
||||
|
||||
def validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["Audio"])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|> CommonValidations.validate_host_match()
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
||||
# based on Pleroma.Web.ActivityPub.Utils.lazy_put_objects_defaults
|
||||
def fix_defaults(data) do
|
||||
%{data: %{"id" => context}, id: context_id} =
|
||||
Utils.create_context(data["context"] || data["conversation"])
|
||||
|
||||
data
|
||||
|> Map.put_new("context", context)
|
||||
|> Map.put_new("context_id", context_id)
|
||||
end
|
||||
|
||||
def fix_attribution(data) do
|
||||
data
|
||||
|> Map.put_new("actor", data["attributedTo"])
|
||||
end
|
||||
end
|
||||
|
|
@ -16,11 +16,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateNoteValidator do
|
|||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:type, :string)
|
||||
field(:to, {:array, :string})
|
||||
field(:cc, {:array, :string})
|
||||
field(:bto, {:array, :string}, default: [])
|
||||
field(:bcc, {:array, :string}, default: [])
|
||||
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
embeds_one(:object, NoteValidator)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
|
|||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:context, :string)
|
||||
field(:content, :string)
|
||||
field(:to, {:array, :string}, default: [])
|
||||
field(:cc, {:array, :string}, default: [])
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
|
|||
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, {:array, :string}, default: [])
|
||||
field(:cc, {:array, :string}, default: [])
|
||||
field(:bto, {:array, :string}, default: [])
|
||||
field(:bcc, {:array, :string}, default: [])
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
# TODO: Write type
|
||||
field(:tag, {:array, :map}, default: [])
|
||||
field(:type, :string)
|
||||
|
|
@ -34,7 +34,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
|
|||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, :string)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:uri, ObjectValidators.Uri)
|
||||
|
||||
field(:likes, {:array, :string}, default: [])
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
|
|
@ -19,10 +19,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
# Extends from NoteValidator
|
||||
embedded_schema do
|
||||
field(:id, ObjectValidators.ObjectID, primary_key: true)
|
||||
field(:to, {:array, :string}, default: [])
|
||||
field(:cc, {:array, :string}, default: [])
|
||||
field(:bto, {:array, :string}, default: [])
|
||||
field(:bcc, {:array, :string}, default: [])
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
field(:bto, ObjectValidators.Recipients, default: [])
|
||||
field(:bcc, ObjectValidators.Recipients, default: [])
|
||||
# TODO: Write type
|
||||
field(:tag, {:array, :map}, default: [])
|
||||
field(:type, :string)
|
||||
|
|
@ -42,7 +42,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
field(:replies_count, :integer, default: 0)
|
||||
field(:like_count, :integer, default: 0)
|
||||
field(:announcement_count, :integer, default: 0)
|
||||
field(:inReplyTo, :string)
|
||||
field(:inReplyTo, ObjectValidators.ObjectID)
|
||||
field(:uri, ObjectValidators.Uri)
|
||||
# short identifier for PleromaFE to group statuses by context
|
||||
field(:context_id, :integer)
|
||||
|
|
@ -81,27 +81,11 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
end
|
||||
end
|
||||
|
||||
# based on Pleroma.Web.ActivityPub.Utils.lazy_put_objects_defaults
|
||||
defp fix_defaults(data) do
|
||||
%{data: %{"id" => context}, id: context_id} =
|
||||
Utils.create_context(data["context"] || data["conversation"])
|
||||
|
||||
data
|
||||
|> Map.put_new_lazy("published", &Utils.make_date/0)
|
||||
|> Map.put_new("context", context)
|
||||
|> Map.put_new("context_id", context_id)
|
||||
end
|
||||
|
||||
defp fix_attribution(data) do
|
||||
data
|
||||
|> Map.put_new("actor", data["attributedTo"])
|
||||
end
|
||||
|
||||
defp fix(data) do
|
||||
data
|
||||
|> fix_attribution()
|
||||
|> CommonFixes.fix_defaults()
|
||||
|> CommonFixes.fix_attribution()
|
||||
|> fix_closed()
|
||||
|> fix_defaults()
|
||||
end
|
||||
|
||||
def changeset(struct, data) do
|
||||
|
|
@ -117,7 +101,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
def validate_data(data_cng) do
|
||||
data_cng
|
||||
|> validate_inclusion(:type, ["Question"])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context])
|
||||
|> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
|
||||
|> CommonValidations.validate_any_presence([:cc, :to])
|
||||
|> CommonValidations.validate_fields_match([:actor, :attributedTo])
|
||||
|> CommonValidations.validate_actor_presence()
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator do
|
|||
field(:type, :string)
|
||||
field(:object, ObjectValidators.ObjectID)
|
||||
field(:actor, ObjectValidators.ObjectID)
|
||||
field(:to, {:array, :string}, default: [])
|
||||
field(:cc, {:array, :string}, default: [])
|
||||
field(:to, ObjectValidators.Recipients, default: [])
|
||||
field(:cc, ObjectValidators.Recipients, default: [])
|
||||
end
|
||||
|
||||
def cast_and_validate(data) do
|
||||
|
|
|
|||
|
|
@ -16,14 +16,70 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.Pipeline
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.Push
|
||||
alias Pleroma.Web.Streamer
|
||||
alias Pleroma.Workers.BackgroundWorker
|
||||
|
||||
require Logger
|
||||
|
||||
def handle(object, meta \\ [])
|
||||
|
||||
# Task this handles
|
||||
# - Follows
|
||||
# - Sends a notification
|
||||
def handle(
|
||||
%{
|
||||
data: %{
|
||||
"actor" => actor,
|
||||
"type" => "Accept",
|
||||
"object" => follow_activity_id
|
||||
}
|
||||
} = object,
|
||||
meta
|
||||
) do
|
||||
with %Activity{actor: follower_id} = follow_activity <-
|
||||
Activity.get_by_ap_id(follow_activity_id),
|
||||
%User{} = followed <- User.get_cached_by_ap_id(actor),
|
||||
%User{} = follower <- User.get_cached_by_ap_id(follower_id),
|
||||
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
|
||||
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do
|
||||
Notification.update_notification_type(followed, follow_activity)
|
||||
User.update_follower_count(followed)
|
||||
User.update_following_count(follower)
|
||||
end
|
||||
|
||||
{:ok, object, meta}
|
||||
end
|
||||
|
||||
# Task this handles
|
||||
# - Rejects all existing follow activities for this person
|
||||
# - Updates the follow state
|
||||
# - Dismisses notification
|
||||
def handle(
|
||||
%{
|
||||
data: %{
|
||||
"actor" => actor,
|
||||
"type" => "Reject",
|
||||
"object" => follow_activity_id
|
||||
}
|
||||
} = object,
|
||||
meta
|
||||
) do
|
||||
with %Activity{actor: follower_id} = follow_activity <-
|
||||
Activity.get_by_ap_id(follow_activity_id),
|
||||
%User{} = followed <- User.get_cached_by_ap_id(actor),
|
||||
%User{} = follower <- User.get_cached_by_ap_id(follower_id),
|
||||
{:ok, _follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject") do
|
||||
FollowingRelationship.update(follower, followed, :follow_reject)
|
||||
Notification.dismiss(follow_activity)
|
||||
end
|
||||
|
||||
{:ok, object, meta}
|
||||
end
|
||||
|
||||
# Tasks this handle
|
||||
# - Follows if possible
|
||||
# - Sends a notification
|
||||
|
|
@ -44,33 +100,13 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
{_, {:ok, _}, _, _} <-
|
||||
{:following, User.follow(follower, followed, :follow_pending), follower, followed} do
|
||||
if followed.local && !followed.locked do
|
||||
Utils.update_follow_state_for_all(object, "accept")
|
||||
FollowingRelationship.update(follower, followed, :follow_accept)
|
||||
User.update_follower_count(followed)
|
||||
User.update_following_count(follower)
|
||||
|
||||
%{
|
||||
to: [following_user],
|
||||
actor: followed,
|
||||
object: follow_id,
|
||||
local: true
|
||||
}
|
||||
|> ActivityPub.accept()
|
||||
{:ok, accept_data, _} = Builder.accept(followed, object)
|
||||
{:ok, _activity, _} = Pipeline.common_pipeline(accept_data, local: true)
|
||||
end
|
||||
else
|
||||
{:following, {:error, _}, follower, followed} ->
|
||||
Utils.update_follow_state_for_all(object, "reject")
|
||||
FollowingRelationship.update(follower, followed, :follow_reject)
|
||||
|
||||
if followed.local do
|
||||
%{
|
||||
to: [follower.ap_id],
|
||||
actor: followed,
|
||||
object: follow_id,
|
||||
local: true
|
||||
}
|
||||
|> ActivityPub.reject()
|
||||
end
|
||||
{:following, {:error, _}, _follower, followed} ->
|
||||
{:ok, reject_data, _} = Builder.reject(followed, object)
|
||||
{:ok, _activity, _} = Pipeline.common_pipeline(reject_data, local: true)
|
||||
|
||||
_ ->
|
||||
nil
|
||||
|
|
@ -217,13 +253,15 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
# - Stream out the activity
|
||||
def handle(%{data: %{"type" => "Delete", "object" => deleted_object}} = object, meta) do
|
||||
deleted_object =
|
||||
Object.normalize(deleted_object, false) || User.get_cached_by_ap_id(deleted_object)
|
||||
Object.normalize(deleted_object, false) ||
|
||||
User.get_cached_by_ap_id(deleted_object)
|
||||
|
||||
result =
|
||||
case deleted_object do
|
||||
%Object{} ->
|
||||
with {:ok, deleted_object, activity} <- Object.delete(deleted_object),
|
||||
%User{} = user <- User.get_cached_by_ap_id(deleted_object.data["actor"]) do
|
||||
{_, actor} when is_binary(actor) <- {:actor, deleted_object.data["actor"]},
|
||||
%User{} = user <- User.get_cached_by_ap_id(actor) do
|
||||
User.remove_pinnned_activity(user, activity)
|
||||
|
||||
{:ok, user} = ActivityPub.decrease_note_count_if_public(user, deleted_object)
|
||||
|
|
@ -237,6 +275,10 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
ActivityPub.stream_out(object)
|
||||
ActivityPub.stream_out_participations(deleted_object, user)
|
||||
:ok
|
||||
else
|
||||
{:actor, _} ->
|
||||
Logger.error("The object doesn't have an actor: #{inspect(deleted_object)}")
|
||||
:no_object_actor
|
||||
end
|
||||
|
||||
%User{} ->
|
||||
|
|
@ -298,7 +340,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_object_creation(%{"type" => "Question"} = object, meta) do
|
||||
def handle_object_creation(%{"type" => objtype} = object, meta)
|
||||
when objtype in ~w[Audio Question] do
|
||||
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
|
||||
{:ok, object, meta}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
alias Pleroma.Activity
|
||||
alias Pleroma.EarmarkRenderer
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
alias Pleroma.FollowingRelationship
|
||||
alias Pleroma.Maps
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Containment
|
||||
alias Pleroma.Repo
|
||||
|
|
@ -391,32 +389,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
|
||||
defp fix_content(object), do: object
|
||||
|
||||
defp mastodon_follow_hack(%{"id" => id, "actor" => follower_id}, followed) do
|
||||
with true <- id =~ "follows",
|
||||
%User{local: true} = follower <- User.get_cached_by_ap_id(follower_id),
|
||||
%Activity{} = activity <- Utils.fetch_latest_follow(follower, followed) do
|
||||
{:ok, activity}
|
||||
else
|
||||
_ -> {:error, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp mastodon_follow_hack(_, _), do: {:error, nil}
|
||||
|
||||
defp get_follow_activity(follow_object, followed) do
|
||||
with object_id when not is_nil(object_id) <- Utils.get_ap_id(follow_object),
|
||||
{_, %Activity{} = activity} <- {:activity, Activity.get_by_ap_id(object_id)} do
|
||||
{:ok, activity}
|
||||
else
|
||||
# Can't find the activity. This might a Mastodon 2.3 "Accept"
|
||||
{:activity, nil} ->
|
||||
mastodon_follow_hack(follow_object, followed)
|
||||
|
||||
_ ->
|
||||
{:error, nil}
|
||||
end
|
||||
end
|
||||
|
||||
# Reduce the object list to find the reported user.
|
||||
defp get_reported(objects) do
|
||||
Enum.reduce_while(objects, nil, fn ap_id, _ ->
|
||||
|
|
@ -489,7 +461,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
%{"type" => "Create", "object" => %{"type" => objtype} = object} = data,
|
||||
options
|
||||
)
|
||||
when objtype in ["Article", "Event", "Note", "Video", "Page", "Audio"] do
|
||||
when objtype in ~w{Article Event Note Video Page} do
|
||||
actor = Containment.get_actor(data)
|
||||
|
||||
with nil <- Activity.get_create_by_object_ap_id(object["id"]),
|
||||
|
|
@ -551,60 +523,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_incoming(
|
||||
%{"type" => "Accept", "object" => follow_object, "actor" => _actor, "id" => id} = data,
|
||||
_options
|
||||
) do
|
||||
with actor <- Containment.get_actor(data),
|
||||
{:ok, %User{} = followed} <- User.get_or_fetch_by_ap_id(actor),
|
||||
{:ok, follow_activity} <- get_follow_activity(follow_object, followed),
|
||||
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
|
||||
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
|
||||
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do
|
||||
User.update_follower_count(followed)
|
||||
User.update_following_count(follower)
|
||||
|
||||
Notification.update_notification_type(followed, follow_activity)
|
||||
|
||||
ActivityPub.accept(%{
|
||||
to: follow_activity.data["to"],
|
||||
type: "Accept",
|
||||
actor: followed,
|
||||
object: follow_activity.data["id"],
|
||||
local: false,
|
||||
activity_id: id
|
||||
})
|
||||
else
|
||||
_e ->
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
||||
def handle_incoming(
|
||||
%{"type" => "Reject", "object" => follow_object, "actor" => _actor, "id" => id} = data,
|
||||
_options
|
||||
) do
|
||||
with actor <- Containment.get_actor(data),
|
||||
{:ok, %User{} = followed} <- User.get_or_fetch_by_ap_id(actor),
|
||||
{:ok, follow_activity} <- get_follow_activity(follow_object, followed),
|
||||
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"),
|
||||
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
|
||||
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_reject),
|
||||
{:ok, activity} <-
|
||||
ActivityPub.reject(%{
|
||||
to: follow_activity.data["to"],
|
||||
type: "Reject",
|
||||
actor: followed,
|
||||
object: follow_activity.data["id"],
|
||||
local: false,
|
||||
activity_id: id
|
||||
}) do
|
||||
{:ok, activity}
|
||||
else
|
||||
_e -> :error
|
||||
end
|
||||
end
|
||||
|
||||
@misskey_reactions %{
|
||||
"like" => "👍",
|
||||
"love" => "❤️",
|
||||
|
|
@ -637,7 +555,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
%{"type" => "Create", "object" => %{"type" => objtype}} = data,
|
||||
_options
|
||||
)
|
||||
when objtype in ["Question", "Answer", "ChatMessage"] do
|
||||
when objtype in ~w{Question Answer ChatMessage Audio} do
|
||||
with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
||||
{:ok, activity}
|
||||
|
|
@ -659,9 +577,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
%{"type" => type} = data,
|
||||
_options
|
||||
)
|
||||
when type in ~w{Update Block Follow} do
|
||||
when type in ~w{Update Block Follow Accept Reject} do
|
||||
with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
|
||||
{:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
||||
{:ok, activity, _} <-
|
||||
Pipeline.common_pipeline(data, local: false) do
|
||||
{:ok, activity}
|
||||
end
|
||||
end
|
||||
|
|
@ -670,7 +589,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
%{"type" => "Delete"} = data,
|
||||
_options
|
||||
) do
|
||||
with {:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
|
||||
with {:ok, activity, _} <-
|
||||
Pipeline.common_pipeline(data, local: false) do
|
||||
{:ok, activity}
|
||||
else
|
||||
{:error, {:validate_object, _}} = e ->
|
||||
|
|
|
|||
|
|
@ -59,12 +59,9 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
|
|||
end
|
||||
|
||||
def visible_for_user?(%{local: local} = activity, nil) do
|
||||
cfg_key =
|
||||
if local,
|
||||
do: :local,
|
||||
else: :remote
|
||||
cfg_key = if local, do: :local, else: :remote
|
||||
|
||||
if Pleroma.Config.get([:restrict_unauthenticated, :activities, cfg_key]),
|
||||
if Pleroma.Config.restrict_unauthenticated_access?(:activities, cfg_key),
|
||||
do: false,
|
||||
else: is_public?(activity)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,29 +26,40 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheController do
|
|||
defdelegate open_api_operation(action), to: Spec.MediaProxyCacheOperation
|
||||
|
||||
def index(%{assigns: %{user: _}} = conn, params) do
|
||||
cursor =
|
||||
:banned_urls_cache
|
||||
|> :ets.table([{:traverse, {:select, Cachex.Query.create(true, :key)}}])
|
||||
|> :qlc.cursor()
|
||||
entries = fetch_entries(params)
|
||||
urls = paginate_entries(entries, params.page, params.page_size)
|
||||
|
||||
urls =
|
||||
case params.page do
|
||||
1 ->
|
||||
:qlc.next_answers(cursor, params.page_size)
|
||||
render(conn, "index.json",
|
||||
urls: urls,
|
||||
page_size: params.page_size,
|
||||
count: length(entries)
|
||||
)
|
||||
end
|
||||
|
||||
_ ->
|
||||
:qlc.next_answers(cursor, (params.page - 1) * params.page_size)
|
||||
:qlc.next_answers(cursor, params.page_size)
|
||||
end
|
||||
defp fetch_entries(params) do
|
||||
MediaProxy.cache_table()
|
||||
|> Cachex.stream!(Cachex.Query.create(true, :key))
|
||||
|> filter_entries(params[:query])
|
||||
end
|
||||
|
||||
:qlc.delete_cursor(cursor)
|
||||
defp filter_entries(stream, query) when is_binary(query) do
|
||||
regex = ~r/#{query}/i
|
||||
|
||||
render(conn, "index.json", urls: urls)
|
||||
stream
|
||||
|> Enum.filter(fn url -> String.match?(url, regex) end)
|
||||
|> Enum.to_list()
|
||||
end
|
||||
|
||||
defp filter_entries(stream, _), do: Enum.to_list(stream)
|
||||
|
||||
defp paginate_entries(entries, page, page_size) do
|
||||
offset = page_size * (page - 1)
|
||||
Enum.slice(entries, offset, page_size)
|
||||
end
|
||||
|
||||
def delete(%{assigns: %{user: _}, body_params: %{urls: urls}} = conn, _) do
|
||||
MediaProxy.remove_from_banned_urls(urls)
|
||||
render(conn, "index.json", urls: urls)
|
||||
json(conn, %{})
|
||||
end
|
||||
|
||||
def purge(%{assigns: %{user: _}, body_params: %{urls: urls, ban: ban}} = conn, _) do
|
||||
|
|
@ -58,6 +69,6 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheController do
|
|||
MediaProxy.put_in_banned_urls(urls)
|
||||
end
|
||||
|
||||
render(conn, "index.json", urls: urls)
|
||||
json(conn, %{})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@
|
|||
defmodule Pleroma.Web.AdminAPI.MediaProxyCacheView do
|
||||
use Pleroma.Web, :view
|
||||
|
||||
def render("index.json", %{urls: urls}) do
|
||||
%{urls: urls}
|
||||
def render("index.json", %{urls: urls, page_size: page_size, count: count}) do
|
||||
%{
|
||||
urls: urls,
|
||||
count: count,
|
||||
page_size: page_size
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
|
|||
operationId: "AdminAPI.MediaProxyCacheController.index",
|
||||
security: [%{"oAuth" => ["read:media_proxy_caches"]}],
|
||||
parameters: [
|
||||
Operation.parameter(
|
||||
:query,
|
||||
:query,
|
||||
%Schema{type: :string, default: nil},
|
||||
"Page"
|
||||
),
|
||||
Operation.parameter(
|
||||
:page,
|
||||
:query,
|
||||
|
|
@ -36,7 +42,26 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
|
|||
| admin_api_params()
|
||||
],
|
||||
responses: %{
|
||||
200 => success_response()
|
||||
200 =>
|
||||
Operation.response(
|
||||
"Array of banned MediaProxy URLs in Cachex",
|
||||
"application/json",
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
count: %Schema{type: :integer},
|
||||
page_size: %Schema{type: :integer},
|
||||
urls: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
description: "MediaProxy URLs"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
@ -61,7 +86,7 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
|
|||
required: true
|
||||
),
|
||||
responses: %{
|
||||
200 => success_response(),
|
||||
200 => empty_object_response(),
|
||||
400 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
|
|
@ -88,25 +113,9 @@ defmodule Pleroma.Web.ApiSpec.Admin.MediaProxyCacheOperation do
|
|||
required: true
|
||||
),
|
||||
responses: %{
|
||||
200 => success_response(),
|
||||
200 => empty_object_response(),
|
||||
400 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp success_response do
|
||||
Operation.response("Array of banned MediaProxy URLs in Cachex", "application/json", %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
urls: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
description: "MediaProxy URLs"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
alias Pleroma.Activity
|
||||
alias Pleroma.ActivityExpiration
|
||||
alias Pleroma.Conversation.Participation
|
||||
alias Pleroma.FollowingRelationship
|
||||
alias Pleroma.Formatter
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.ThreadMute
|
||||
alias Pleroma.User
|
||||
|
|
@ -122,33 +120,16 @@ defmodule Pleroma.Web.CommonAPI do
|
|||
|
||||
def accept_follow_request(follower, followed) do
|
||||
with %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
|
||||
{:ok, follower} <- User.follow(follower, followed),
|
||||
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
|
||||
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept),
|
||||
{:ok, _activity} <-
|
||||
ActivityPub.accept(%{
|
||||
to: [follower.ap_id],
|
||||
actor: followed,
|
||||
object: follow_activity.data["id"],
|
||||
type: "Accept"
|
||||
}) do
|
||||
Notification.update_notification_type(followed, follow_activity)
|
||||
{:ok, accept_data, _} <- Builder.accept(followed, follow_activity),
|
||||
{:ok, _activity, _} <- Pipeline.common_pipeline(accept_data, local: true) do
|
||||
{:ok, follower}
|
||||
end
|
||||
end
|
||||
|
||||
def reject_follow_request(follower, followed) do
|
||||
with %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
|
||||
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"),
|
||||
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_reject),
|
||||
{:ok, _notifications} <- Notification.dismiss(follow_activity),
|
||||
{:ok, _activity} <-
|
||||
ActivityPub.reject(%{
|
||||
to: [follower.ap_id],
|
||||
actor: followed,
|
||||
object: follow_activity.data["id"],
|
||||
type: "Reject"
|
||||
}) do
|
||||
{:ok, reject_data, _} <- Builder.reject(followed, follow_activity),
|
||||
{:ok, _activity, _} <- Pipeline.common_pipeline(reject_data, local: true) do
|
||||
{:ok, follower}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
import Pleroma.Web.ControllerHelper,
|
||||
only: [add_link_headers: 2, add_link_headers: 3]
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Pagination
|
||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
|
|
@ -89,11 +90,11 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
end
|
||||
|
||||
defp restrict_unauthenticated?(true = _local_only) do
|
||||
Pleroma.Config.get([:restrict_unauthenticated, :timelines, :local])
|
||||
Config.restrict_unauthenticated_access?(:timelines, :local)
|
||||
end
|
||||
|
||||
defp restrict_unauthenticated?(_) do
|
||||
Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated])
|
||||
Config.restrict_unauthenticated_access?(:timelines, :federated)
|
||||
end
|
||||
|
||||
# GET /api/v1/timelines/public
|
||||
|
|
|
|||
|
|
@ -9,28 +9,31 @@ defmodule Pleroma.Web.MediaProxy do
|
|||
alias Pleroma.Web.MediaProxy.Invalidation
|
||||
|
||||
@base64_opts [padding: false]
|
||||
@cache_table :banned_urls_cache
|
||||
|
||||
def cache_table, do: @cache_table
|
||||
|
||||
@spec in_banned_urls(String.t()) :: boolean()
|
||||
def in_banned_urls(url), do: elem(Cachex.exists?(:banned_urls_cache, url(url)), 1)
|
||||
def in_banned_urls(url), do: elem(Cachex.exists?(@cache_table, url(url)), 1)
|
||||
|
||||
def remove_from_banned_urls(urls) when is_list(urls) do
|
||||
Cachex.execute!(:banned_urls_cache, fn cache ->
|
||||
Cachex.execute!(@cache_table, fn cache ->
|
||||
Enum.each(Invalidation.prepare_urls(urls), &Cachex.del(cache, &1))
|
||||
end)
|
||||
end
|
||||
|
||||
def remove_from_banned_urls(url) when is_binary(url) do
|
||||
Cachex.del(:banned_urls_cache, url(url))
|
||||
Cachex.del(@cache_table, url(url))
|
||||
end
|
||||
|
||||
def put_in_banned_urls(urls) when is_list(urls) do
|
||||
Cachex.execute!(:banned_urls_cache, fn cache ->
|
||||
Cachex.execute!(@cache_table, fn cache ->
|
||||
Enum.each(Invalidation.prepare_urls(urls), &Cachex.put(cache, &1, true))
|
||||
end)
|
||||
end
|
||||
|
||||
def put_in_banned_urls(url) when is_binary(url) do
|
||||
Cachex.put(:banned_urls_cache, url(url), true)
|
||||
Cachex.put(@cache_table, url(url), true)
|
||||
end
|
||||
|
||||
def url(url) when is_nil(url) or url == "", do: nil
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ defmodule Pleroma.Web.Preload.Providers.Timelines do
|
|||
end
|
||||
|
||||
def build_public_tag(acc, params) do
|
||||
if Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated], true) do
|
||||
if Pleroma.Config.restrict_unauthenticated_access?(:timelines, :federated) do
|
||||
acc
|
||||
else
|
||||
Map.put(acc, @public_url, public_timeline(params))
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ defmodule Pleroma.Workers.Cron.ClearOauthTokenWorker do
|
|||
def perform(_job) do
|
||||
if Config.get([:oauth2, :clean_expired_tokens], false) do
|
||||
Token.delete_expired_tokens()
|
||||
else
|
||||
:ok
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ defmodule Pleroma.Workers.Cron.DigestEmailsWorker do
|
|||
)
|
||||
|> Repo.all()
|
||||
|> send_emails
|
||||
else
|
||||
:ok
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
def send_emails(users) do
|
||||
|
|
|
|||
|
|
@ -55,11 +55,9 @@ defmodule Pleroma.Workers.Cron.NewUsersDigestWorker do
|
|||
|> Repo.all()
|
||||
|> Enum.map(&Pleroma.Emails.NewUsersDigestEmail.new_users(&1, users_and_statuses))
|
||||
|> Enum.each(&Pleroma.Emails.Mailer.deliver/1)
|
||||
else
|
||||
:ok
|
||||
end
|
||||
else
|
||||
:ok
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker do
|
|||
def perform(_job) do
|
||||
if Config.get([ActivityExpiration, :enabled]) do
|
||||
Enum.each(ActivityExpiration.due_expirations(@interval), &delete_activity/1)
|
||||
else
|
||||
:ok
|
||||
end
|
||||
after
|
||||
:ok
|
||||
end
|
||||
|
||||
def delete_activity(%ActivityExpiration{activity_id: activity_id}) do
|
||||
|
|
@ -41,7 +41,7 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker do
|
|||
|
||||
{:user, _} ->
|
||||
Logger.error(
|
||||
"#{__MODULE__} Couldn't delete expired activity: not found actorof ##{activity_id}"
|
||||
"#{__MODULE__} Couldn't delete expired activity: not found actor of ##{activity_id}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,5 +12,6 @@ defmodule Pleroma.Workers.Cron.StatsWorker do
|
|||
@impl Oban.Worker
|
||||
def perform(_job) do
|
||||
Pleroma.Stats.do_collect()
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue