Merge branch 'split-federation' into 'master'

Split federation

See merge request framasoft/mobilizon!382
This commit is contained in:
Thomas Citharel 2020-01-24 22:20:15 +01:00
commit a7acf17a4a
143 changed files with 866 additions and 774 deletions

View File

@ -44,7 +44,7 @@ config :mobilizon, MobilizonWeb.Endpoint,
# Upload configuration # Upload configuration
config :mobilizon, MobilizonWeb.Upload, config :mobilizon, MobilizonWeb.Upload,
uploader: MobilizonWeb.Uploaders.Local, uploader: MobilizonWeb.Upload.Uploader.Local,
filters: [ filters: [
MobilizonWeb.Upload.Filter.Dedupe, MobilizonWeb.Upload.Filter.Dedupe,
MobilizonWeb.Upload.Filter.Optimize MobilizonWeb.Upload.Filter.Optimize
@ -60,7 +60,7 @@ config :mobilizon, MobilizonWeb.Upload,
] ]
] ]
config :mobilizon, MobilizonWeb.Uploaders.Local, uploads: "uploads" config :mobilizon, MobilizonWeb.Upload.Uploader.Local, uploads: "uploads"
config :mobilizon, :media_proxy, config :mobilizon, :media_proxy,
enabled: true, enabled: true,
@ -78,7 +78,7 @@ config :logger, :console,
format: "$time $metadata[$level] $message\n", format: "$time $metadata[$level] $message\n",
metadata: [:request_id] metadata: [:request_id]
config :mobilizon, MobilizonWeb.Guardian, config :mobilizon, MobilizonWeb.Auth.Guardian,
issuer: "mobilizon", issuer: "mobilizon",
secret_key: "ty0WM7YBE3ojvxoUQxo8AERrNpfbXnIJ82ovkPdqbUFw31T5LcK8wGjaOiReVQjo" secret_key: "ty0WM7YBE3ojvxoUQxo8AERrNpfbXnIJ82ovkPdqbUFw31T5LcK8wGjaOiReVQjo"
@ -120,7 +120,7 @@ config :ex_cldr,
default_backend: Mobilizon.Cldr default_backend: Mobilizon.Cldr
config :http_signatures, config :http_signatures,
adapter: Mobilizon.Service.HTTPSignatures.Signature adapter: Mobilizon.Federation.HTTPSignatures.Signature
config :mobilizon, :activitypub, sign_object_fetches: true config :mobilizon, :activitypub, sign_object_fetches: true

View File

@ -34,7 +34,7 @@ config :mobilizon, MobilizonWeb.Email.Mailer, adapter: Bamboo.TestAdapter
config :mobilizon, MobilizonWeb.Upload, filters: [], link_name: false config :mobilizon, MobilizonWeb.Upload, filters: [], link_name: false
config :mobilizon, MobilizonWeb.Uploaders.Local, uploads: "test/uploads" config :mobilizon, MobilizonWeb.Upload.Uploader.Local, uploads: "test/uploads"
config :exvcr, config :exvcr,
vcr_cassette_library_dir: "test/fixtures/vcr_cassettes" vcr_cassette_library_dir: "test/fixtures/vcr_cassettes"

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Activity do defmodule Mobilizon.Federation.ActivityPub.Activity do
@moduledoc """ @moduledoc """
Represents an activity. Represents an activity.
""" """

View File

@ -3,25 +3,34 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/activity_pub.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/activity_pub.ex
defmodule Mobilizon.Service.ActivityPub do defmodule Mobilizon.Federation.ActivityPub do
@moduledoc """ @moduledoc """
# ActivityPub context. The ActivityPub context.
""" """
import Mobilizon.Service.ActivityPub.Utils import Mobilizon.Federation.ActivityPub.Utils
import Mobilizon.Service.ActivityPub.Visibility
alias Mobilizon.{Actors, Config, Events, Reports, Users, Share} alias Mobilizon.{Actors, Config, Events, Reports, Users, Share}
alias Mobilizon.Actors.{Actor, Follower} alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Events.{Comment, Event, Participant} alias Mobilizon.Events.{Comment, Event, Participant}
alias Mobilizon.Reports.Report alias Mobilizon.Reports.Report
alias Mobilizon.Tombstone alias Mobilizon.Tombstone
alias Mobilizon.Service.ActivityPub.{Activity, Converter, Convertible, Relay, Transmogrifier}
alias Mobilizon.Service.{Federator, WebFinger} alias Mobilizon.Federation.ActivityPub.{
alias Mobilizon.Service.HTTPSignatures.Signature Activity,
Audience,
Federator,
Relay,
Transmogrifier,
Visibility
}
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
alias Mobilizon.Federation.HTTPSignatures.Signature
alias Mobilizon.Federation.WebFinger
alias MobilizonWeb.API.Utils, as: APIUtils alias MobilizonWeb.API.Utils, as: APIUtils
alias Mobilizon.Service.ActivityPub.Audience
alias Mobilizon.Service.ActivityPub.Converter.Utils, as: ConverterUtils
alias MobilizonWeb.Email.{Admin, Mailer} alias MobilizonWeb.Email.{Admin, Mailer}
require Logger require Logger
@ -29,7 +38,7 @@ defmodule Mobilizon.Service.ActivityPub do
@doc """ @doc """
Wraps an object into an activity Wraps an object into an activity
""" """
@spec create_activity(map(), boolean()) :: {:ok, %Activity{}} @spec create_activity(map, boolean) :: {:ok, Activity.t()}
def create_activity(map, local \\ true) when is_map(map) do def create_activity(map, local \\ true) when is_map(map) do
with map <- lazy_put_activity_defaults(map) do with map <- lazy_put_activity_defaults(map) do
{:ok, {:ok,
@ -50,7 +59,7 @@ defmodule Mobilizon.Service.ActivityPub do
def fetch_object_from_url(url) do def fetch_object_from_url(url) do
Logger.info("Fetching object from url #{url}") Logger.info("Fetching object from url #{url}")
date = Mobilizon.Service.HTTPSignatures.Signature.generate_date_header() date = Signature.generate_date_header()
headers = headers =
[{:Accept, "application/activity+json"}] [{:Accept, "application/activity+json"}]
@ -149,7 +158,7 @@ defmodule Mobilizon.Service.ActivityPub do
* Creates the object, which returns AS data * Creates the object, which returns AS data
* Wraps ActivityStreams data into a `Create` activity * Wraps ActivityStreams data into a `Create` activity
* Creates an `Mobilizon.Service.ActivityPub.Activity` from this * Creates an `Mobilizon.Federation.ActivityPub.Activity` from this
* Federates (asynchronously) the activity * Federates (asynchronously) the activity
* Returns the activity * Returns the activity
""" """
@ -181,7 +190,7 @@ defmodule Mobilizon.Service.ActivityPub do
* Updates the object, which returns AS data * Updates the object, which returns AS data
* Wraps ActivityStreams data into a `Update` activity * Wraps ActivityStreams data into a `Update` activity
* Creates an `Mobilizon.Service.ActivityPub.Activity` from this * Creates an `Mobilizon.Federation.ActivityPub.Activity` from this
* Federates (asynchronously) the activity * Federates (asynchronously) the activity
* Returns the activity * Returns the activity
""" """
@ -251,7 +260,7 @@ defmodule Mobilizon.Service.ActivityPub do
local \\ true, local \\ true,
public \\ true public \\ true
) do ) do
with true <- is_public?(object), with true <- Visibility.is_public?(object),
{:ok, %Actor{id: object_owner_actor_id}} <- Actors.get_actor_by_url(object["actor"]), {:ok, %Actor{id: object_owner_actor_id}} <- Actors.get_actor_by_url(object["actor"]),
{:ok, %Share{} = _share} <- Share.create(object["id"], actor.id, object_owner_actor_id), {:ok, %Share{} = _share} <- Share.create(object["id"], actor.id, object_owner_actor_id),
announce_data <- make_announce_data(actor, object, activity_id, public), announce_data <- make_announce_data(actor, object, activity_id, public),
@ -549,7 +558,7 @@ defmodule Mobilizon.Service.ActivityPub do
Logger.debug("Publishing an activity") Logger.debug("Publishing an activity")
Logger.debug(inspect(activity)) Logger.debug(inspect(activity))
public = is_public?(activity) public = Visibility.is_public?(activity)
Logger.debug("is public ? #{public}") Logger.debug("is public ? #{public}")
if public && is_create_activity?(activity) && Config.get([:instance, :allow_relay]) do if public && is_create_activity?(activity) && Config.get([:instance, :allow_relay]) do
@ -629,7 +638,7 @@ defmodule Mobilizon.Service.ActivityPub do
:ok <- Logger.debug("response okay, now decoding json"), :ok <- Logger.debug("response okay, now decoding json"),
{:ok, data} <- Jason.decode(body) do {:ok, data} <- Jason.decode(body) do
Logger.debug("Got activity+json response at actor's endpoint, now converting data") Logger.debug("Got activity+json response at actor's endpoint, now converting data")
Mobilizon.Service.ActivityPub.Converter.Actor.as_to_model_data(data) Converter.Actor.as_to_model_data(data)
else else
# Actor is gone, probably deleted # Actor is gone, probably deleted
{:ok, %HTTPoison.Response{status_code: 410}} -> {:ok, %HTTPoison.Response{status_code: 410}} ->
@ -653,9 +662,7 @@ defmodule Mobilizon.Service.ActivityPub do
{:ok, comments, total_comments} = Events.list_public_comments_for_actor(actor, page, limit) {:ok, comments, total_comments} = Events.list_public_comments_for_actor(actor, page, limit)
event_activities = Enum.map(events, &event_to_activity/1) event_activities = Enum.map(events, &event_to_activity/1)
comment_activities = Enum.map(comments, &comment_to_activity/1) comment_activities = Enum.map(comments, &comment_to_activity/1)
activities = event_activities ++ comment_activities activities = event_activities ++ comment_activities
%{elements: activities, total: total_events + total_comments} %{elements: activities, total: total_events + total_comments}
@ -731,13 +738,8 @@ defmodule Mobilizon.Service.ActivityPub do
defp check_for_tombstones(%{url: url}), do: Tombstone.find_tombstone(url) defp check_for_tombstones(%{url: url}), do: Tombstone.find_tombstone(url)
defp check_for_tombstones(_), do: nil defp check_for_tombstones(_), do: nil
@spec update_event(Event.t(), map(), map()) :: @spec update_event(Event.t(), map(), map()) :: {:ok, Event.t(), Activity.t()} | any()
{:ok, Event.t(), Activity.t()} | any() defp update_event(%Event{} = old_event, args, additional) do
defp update_event(
%Event{} = old_event,
args,
additional
) do
with args <- prepare_args_for_event(args), with args <- prepare_args_for_event(args),
{:ok, %Event{} = new_event} <- Events.update_event(old_event, args), {:ok, %Event{} = new_event} <- Events.update_event(old_event, args),
{:ok, true} <- Cachex.del(:activity_pub, "event_#{new_event.uuid}"), {:ok, true} <- Cachex.del(:activity_pub, "event_#{new_event.uuid}"),
@ -754,8 +756,7 @@ defmodule Mobilizon.Service.ActivityPub do
end end
end end
@spec update_actor(Actor.t(), map(), map()) :: @spec update_actor(Actor.t(), map, map) :: {:ok, Actor.t(), Activity.t()} | any
{:ok, Actor.t(), Activity.t()} | any()
defp update_actor(%Actor{} = old_actor, args, additional) do defp update_actor(%Actor{} = old_actor, args, additional) do
with {:ok, %Actor{} = new_actor} <- Actors.update_actor(old_actor, args), with {:ok, %Actor{} = new_actor} <- Actors.update_actor(old_actor, args),
actor_as_data <- Convertible.model_to_as(new_actor), actor_as_data <- Convertible.model_to_as(new_actor),
@ -768,12 +769,8 @@ defmodule Mobilizon.Service.ActivityPub do
end end
end end
@spec accept_follow(Follower.t(), map()) :: @spec accept_follow(Follower.t(), map) :: {:ok, Follower.t(), Activity.t()} | any
{:ok, Follower.t(), Activity.t()} | any() defp accept_follow(%Follower{} = follower, additional) do
defp accept_follow(
%Follower{} = follower,
additional
) do
with {:ok, %Follower{} = follower} <- Actors.update_follower(follower, %{approved: true}), with {:ok, %Follower{} = follower} <- Actors.update_follower(follower, %{approved: true}),
follower_as_data <- Convertible.model_to_as(follower), follower_as_data <- Convertible.model_to_as(follower),
update_data <- update_data <-
@ -795,12 +792,8 @@ defmodule Mobilizon.Service.ActivityPub do
end end
end end
@spec accept_join(Participant.t(), map()) :: @spec accept_join(Participant.t(), map) :: {:ok, Participant.t(), Activity.t()} | any
{:ok, Participant.t(), Activity.t()} | any() defp accept_join(%Participant{} = participant, additional) do
defp accept_join(
%Participant{} = participant,
additional
) do
with {:ok, %Participant{} = participant} <- with {:ok, %Participant{} = participant} <-
Events.update_participant(participant, %{role: :participant}), Events.update_participant(participant, %{role: :participant}),
Absinthe.Subscription.publish(MobilizonWeb.Endpoint, participant.actor, Absinthe.Subscription.publish(MobilizonWeb.Endpoint, participant.actor,
@ -825,8 +818,7 @@ defmodule Mobilizon.Service.ActivityPub do
end end
end end
@spec reject_join(Participant.t(), map()) :: @spec reject_join(Participant.t(), map()) :: {:ok, Participant.t(), Activity.t()} | any()
{:ok, Participant.t(), Activity.t()} | any()
defp reject_join(%Participant{} = participant, additional) do defp reject_join(%Participant{} = participant, additional) do
with {:ok, %Participant{} = participant} <- with {:ok, %Participant{} = participant} <-
Events.update_participant(participant, %{approved: false, role: :rejected}), Events.update_participant(participant, %{approved: false, role: :rejected}),
@ -857,8 +849,7 @@ defmodule Mobilizon.Service.ActivityPub do
end end
end end
@spec reject_follow(Follower.t(), map()) :: @spec reject_follow(Follower.t(), map()) :: {:ok, Follower.t(), Activity.t()} | any()
{:ok, Follower.t(), Activity.t()} | any()
defp reject_follow(%Follower{} = follower, additional) do defp reject_follow(%Follower{} = follower, additional) do
with {:ok, %Follower{} = follower} <- Actors.delete_follower(follower), with {:ok, %Follower{} = follower} <- Actors.delete_follower(follower),
follower_as_data <- Convertible.model_to_as(follower), follower_as_data <- Convertible.model_to_as(follower),

View File

@ -1,13 +1,13 @@
defmodule Mobilizon.Service.ActivityPub.Audience do defmodule Mobilizon.Federation.ActivityPub.Audience do
@moduledoc """ @moduledoc """
Tools for calculating content audience Tools for calculating content audience
""" """
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events.Comment alias Mobilizon.Events.{Comment, Event, Participant}
alias Mobilizon.Events.Event
alias Mobilizon.Events.Participant
alias Mobilizon.Share alias Mobilizon.Share
require Logger require Logger
@ap_public "https://www.w3.org/ns/activitystreams#Public" @ap_public "https://www.w3.org/ns/activitystreams#Public"

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/federator/federator.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/federator/federator.ex
defmodule Mobilizon.Service.Federator do defmodule Mobilizon.Federation.ActivityPub.Federator do
@moduledoc """ @moduledoc """
Handle federated activities Handle federated activities
""" """
@ -11,8 +11,9 @@ defmodule Mobilizon.Service.Federator do
use GenServer use GenServer
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Activity, Transmogrifier} alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier}
require Logger require Logger

View File

@ -3,16 +3,17 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/relay.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/relay.ex
defmodule Mobilizon.Service.ActivityPub.Relay do defmodule Mobilizon.Federation.ActivityPub.Relay do
@moduledoc """ @moduledoc """
Handles following and unfollowing relays and instances. Handles following and unfollowing relays and instances.
""" """
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.{Actor, Follower} alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Activity, Transmogrifier} alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Service.WebFinger alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier}
alias Mobilizon.Federation.WebFinger
alias MobilizonWeb.API.Follows alias MobilizonWeb.API.Follows

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/transmogrifier.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/transmogrifier.ex
defmodule Mobilizon.Service.ActivityPub.Transmogrifier do defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
@moduledoc """ @moduledoc """
A module to handle coding from internal to wire ActivityPub and back. A module to handle coding from internal to wire ActivityPub and back.
""" """
@ -12,11 +12,12 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
alias Mobilizon.Actors.{Actor, Follower} alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.{Comment, Event, Participant} alias Mobilizon.Events.{Comment, Event, Participant}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Activity, Converter, Convertible, Utils}
alias MobilizonWeb.Email.Participation
import Mobilizon.Service.ActivityPub.Utils alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.{Activity, Utils}
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
alias MobilizonWeb.Email.Participation
require Logger require Logger
@ -117,7 +118,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
"id" => id "id" => id
} = data } = data
) do ) do
with actor_url <- get_actor(data), with actor_url <- Utils.get_actor(data),
{:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor_url), {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor_url),
{:object_not_found, {:ok, %Activity{} = activity, object}} <- {:object_not_found, {:ok, %Activity{} = activity, object}} <-
{:object_not_found, {:object_not_found,
@ -146,7 +147,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
def handle_incoming( def handle_incoming(
%{"type" => "Reject", "object" => rejected_object, "actor" => _actor, "id" => id} = data %{"type" => "Reject", "object" => rejected_object, "actor" => _actor, "id" => id} = data
) do ) do
with actor_url <- get_actor(data), with actor_url <- Utils.get_actor(data),
{:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor_url), {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor_url),
{:object_not_found, {:ok, activity, object}} <- {:object_not_found, {:ok, activity, object}} <-
{:object_not_found, {:object_not_found,
@ -175,14 +176,13 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
def handle_incoming( def handle_incoming(
%{"type" => "Announce", "object" => object, "actor" => _actor, "id" => _id} = data %{"type" => "Announce", "object" => object, "actor" => _actor, "id" => _id} = data
) do ) do
with actor <- get_actor(data), with actor <- Utils.get_actor(data),
# TODO: Is the following line useful? # TODO: Is the following line useful?
{:ok, %Actor{id: actor_id} = _actor} <- ActivityPub.get_or_fetch_actor_by_url(actor), {:ok, %Actor{id: actor_id} = _actor} <- ActivityPub.get_or_fetch_actor_by_url(actor),
:ok <- Logger.debug("Fetching contained object"), :ok <- Logger.debug("Fetching contained object"),
{:ok, object} <- fetch_obj_helper_as_activity_streams(object), {:ok, object} <- fetch_obj_helper_as_activity_streams(object),
:ok <- Logger.debug("Handling contained object"), :ok <- Logger.debug("Handling contained object"),
create_data <- create_data <- Utils.make_create_data(object),
make_create_data(object),
:ok <- Logger.debug(inspect(object)), :ok <- Logger.debug(inspect(object)),
{:ok, _activity, entity} <- handle_incoming(create_data), {:ok, _activity, entity} <- handle_incoming(create_data),
:ok <- Logger.debug("Finished processing contained object"), :ok <- Logger.debug("Finished processing contained object"),
@ -221,13 +221,12 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
%{"type" => "Update", "object" => %{"type" => "Event"} = object, "actor" => _actor} = %{"type" => "Update", "object" => %{"type" => "Event"} = object, "actor" => _actor} =
update_data update_data
) do ) do
with actor <- get_actor(update_data), with actor <- Utils.get_actor(update_data),
{:ok, %Actor{url: actor_url}} <- Actors.get_actor_by_url(actor), {:ok, %Actor{url: actor_url}} <- Actors.get_actor_by_url(actor),
{:ok, %Event{} = old_event} <- {:ok, %Event{} = old_event} <-
object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(), object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(),
{:ok, object_data} <- {:ok, object_data} <- Converter.Event.as_to_model_data(object),
object |> Converter.Event.as_to_model_data(), {:origin_check, true} <- {:origin_check, Utils.origin_check?(actor_url, update_data)},
{:origin_check, true} <- {:origin_check, origin_check?(actor_url, update_data)},
{:ok, %Activity{} = activity, %Event{} = new_event} <- {:ok, %Activity{} = activity, %Event{} = new_event} <-
ActivityPub.update(:event, old_event, object_data, false) do ActivityPub.update(:event, old_event, object_data, false) do
{:ok, activity, new_event} {:ok, activity, new_event}
@ -249,7 +248,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
"id" => id "id" => id
} = data } = data
) do ) do
with actor <- get_actor(data), with actor <- Utils.get_actor(data),
{:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor), {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(actor),
{:ok, object} <- fetch_obj_helper_as_activity_streams(object_id), {:ok, object} <- fetch_obj_helper_as_activity_streams(object_id),
{:ok, activity, object} <- {:ok, activity, object} <-
@ -287,10 +286,11 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
def handle_incoming( def handle_incoming(
%{"type" => "Delete", "object" => object, "actor" => _actor, "id" => _id} = data %{"type" => "Delete", "object" => object, "actor" => _actor, "id" => _id} = data
) do ) do
with actor <- get_actor(data), with actor <- Utils.get_actor(data),
{:ok, %Actor{url: actor_url}} <- Actors.get_actor_by_url(actor), {:ok, %Actor{url: actor_url}} <- Actors.get_actor_by_url(actor),
object_id <- Utils.get_url(object), object_id <- Utils.get_url(object),
{:origin_check, true} <- {:origin_check, origin_check_from_id?(actor_url, object_id)}, {:origin_check, true} <-
{:origin_check, Utils.origin_check_from_id?(actor_url, object_id)},
{:ok, object} <- ActivityPub.fetch_object_from_url(object_id), {:ok, object} <- ActivityPub.fetch_object_from_url(object_id),
{:ok, activity, object} <- ActivityPub.delete(object, false) do {:ok, activity, object} <- ActivityPub.delete(object, false) do
{:ok, activity, object} {:ok, activity, object}
@ -308,7 +308,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
def handle_incoming( def handle_incoming(
%{"type" => "Join", "object" => object, "actor" => _actor, "id" => id} = data %{"type" => "Join", "object" => object, "actor" => _actor, "id" => id} = data
) do ) do
with actor <- get_actor(data), with actor <- Utils.get_actor(data),
{:ok, %Actor{url: _actor_url} = actor} <- Actors.get_actor_by_url(actor), {:ok, %Actor{url: _actor_url} = actor} <- Actors.get_actor_by_url(actor),
object <- Utils.get_url(object), object <- Utils.get_url(object),
{:ok, object} <- ActivityPub.fetch_object_from_url(object), {:ok, object} <- ActivityPub.fetch_object_from_url(object),
@ -324,7 +324,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
def handle_incoming( def handle_incoming(
%{"type" => "Leave", "object" => object, "actor" => actor, "id" => _id} = data %{"type" => "Leave", "object" => object, "actor" => actor, "id" => _id} = data
) do ) do
with actor <- get_actor(data), with actor <- Utils.get_actor(data),
{:ok, %Actor{} = actor} <- Actors.get_actor_by_url(actor), {:ok, %Actor{} = actor} <- Actors.get_actor_by_url(actor),
object <- Utils.get_url(object), object <- Utils.get_url(object),
{:ok, object} <- ActivityPub.fetch_object_from_url(object), {:ok, object} <- ActivityPub.fetch_object_from_url(object),
@ -356,7 +356,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
# "id" => id # "id" => id
# } = data # } = data
# ) do # ) do
# with actor <- get_actor(data), # with actor <- Utils.get_actor(data),
# %Actor{} = actor <- ActivityPub.get_or_fetch_actor_by_url(actor), # %Actor{} = actor <- ActivityPub.get_or_fetch_actor_by_url(actor),
# {:ok, object} <- fetch_obj_helper(object_id) || fetch_obj_helper(object_id), # {:ok, object} <- fetch_obj_helper(object_id) || fetch_obj_helper(object_id),
# {:ok, activity, _, _} <- ActivityPub.unlike(actor, object, id, false) do # {:ok, activity, _, _} <- ActivityPub.unlike(actor, object, id, false) do

View File

@ -3,16 +3,18 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/utils.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/utils.ex
defmodule Mobilizon.Service.ActivityPub.Utils do defmodule Mobilizon.Federation.ActivityPub.Utils do
@moduledoc """ @moduledoc """
# Various ActivityPub related utils. Various ActivityPub related utils.
""" """
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Media.Picture alias Mobilizon.Media.Picture
alias Mobilizon.Service.ActivityPub.{Activity, Converter}
alias Mobilizon.Service.Federator alias Mobilizon.Federation.ActivityPub.{Activity, Federator, Relay}
alias Mobilizon.Federation.ActivityStream.Converter
alias Mobilizon.Federation.HTTPSignatures
require Logger require Logger
@ -422,8 +424,8 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
uri = URI.parse(id) uri = URI.parse(id)
signature = signature =
Mobilizon.Service.ActivityPub.Relay.get_actor() Relay.get_actor()
|> Mobilizon.Service.HTTPSignatures.Signature.sign(%{ |> HTTPSignatures.Signature.sign(%{
"(request-target)": "get #{uri.path}", "(request-target)": "get #{uri.path}",
host: uri.host, host: uri.host,
date: date date: date

View File

@ -3,13 +3,14 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/visibility.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/visibility.ex
defmodule Mobilizon.Service.ActivityPub.Visibility do defmodule Mobilizon.Federation.ActivityPub.Visibility do
@moduledoc """ @moduledoc """
Utility functions related to content visibility Utility functions related to content visibility
""" """
alias Mobilizon.Events.Comment alias Mobilizon.Events.Comment
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Federation.ActivityPub.Activity
@public "https://www.w3.org/ns/activitystreams#Public" @public "https://www.w3.org/ns/activitystreams#Public"
@ -18,8 +19,9 @@ defmodule Mobilizon.Service.ActivityPub.Visibility do
def is_public?(%{data: data}), do: is_public?(data) def is_public?(%{data: data}), do: is_public?(data)
def is_public?(%Activity{data: data}), do: is_public?(data) def is_public?(%Activity{data: data}), do: is_public?(data)
def is_public?(data) when is_map(data), def is_public?(data) when is_map(data) do
do: @public in (Map.get(data, "to", []) ++ Map.get(data, "cc", [])) @public in (Map.get(data, "to", []) ++ Map.get(data, "cc", []))
end
def is_public?(%Comment{deleted_at: deleted_at}), do: !is_nil(deleted_at) def is_public?(%Comment{deleted_at: deleted_at}), do: !is_nil(deleted_at)
def is_public?(err), do: raise(ArgumentError, message: "Invalid argument #{inspect(err)}") def is_public?(err), do: raise(ArgumentError, message: "Invalid argument #{inspect(err)}")

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Actor do defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
@moduledoc """ @moduledoc """
Actor converter. Actor converter.
@ -7,12 +7,14 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Actor do
""" """
alias Mobilizon.Actors.Actor, as: ActorModel alias Mobilizon.Actors.Actor, as: ActorModel
alias Mobilizon.Service.ActivityPub.{Converter, Convertible, Utils}
alias Mobilizon.Federation.ActivityPub.Utils
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
@behaviour Converter @behaviour Converter
defimpl Convertible, for: ActorModel do defimpl Convertible, for: ActorModel do
alias Mobilizon.Service.ActivityPub.Converter.Actor, as: ActorConverter alias Mobilizon.Federation.ActivityStream.Converter.Actor, as: ActorConverter
defdelegate model_to_as(actor), to: ActorConverter defdelegate model_to_as(actor), to: ActorConverter
end end

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Address do defmodule Mobilizon.Federation.ActivityStream.Converter.Address do
@moduledoc """ @moduledoc """
Address converter. Address converter.
@ -7,7 +7,8 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Address do
""" """
alias Mobilizon.Addresses.Address, as: AddressModel alias Mobilizon.Addresses.Address, as: AddressModel
alias Mobilizon.Service.ActivityPub.Converter
alias Mobilizon.Federation.ActivityStream.Converter
@behaviour Converter @behaviour Converter

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Comment do defmodule Mobilizon.Federation.ActivityStream.Converter.Comment do
@moduledoc """ @moduledoc """
Comment converter. Comment converter.
@ -9,17 +9,19 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Comment do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events.Comment, as: CommentModel alias Mobilizon.Events.Comment, as: CommentModel
alias Mobilizon.Events.Event alias Mobilizon.Events.Event
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Converter, Convertible, Visibility}
alias Mobilizon.Service.ActivityPub.Converter.Utils, as: ConverterUtils
alias Mobilizon.Tombstone, as: TombstoneModel alias Mobilizon.Tombstone, as: TombstoneModel
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Visibility
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
require Logger require Logger
@behaviour Converter @behaviour Converter
defimpl Convertible, for: CommentModel do defimpl Convertible, for: CommentModel do
alias Mobilizon.Service.ActivityPub.Converter.Comment, as: CommentConverter alias Mobilizon.Federation.ActivityStream.Converter.Comment, as: CommentConverter
defdelegate model_to_as(comment), to: CommentConverter defdelegate model_to_as(comment), to: CommentConverter
end end

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter do defmodule Mobilizon.Federation.ActivityStream.Converter do
@moduledoc """ @moduledoc """
Converter behaviour. Converter behaviour.

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Event do defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
@moduledoc """ @moduledoc """
Event converter. Event converter.
@ -11,18 +11,19 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Event do
alias Mobilizon.Addresses.Address alias Mobilizon.Addresses.Address
alias Mobilizon.Events.Event, as: EventModel alias Mobilizon.Events.Event, as: EventModel
alias Mobilizon.Media.Picture alias Mobilizon.Media.Picture
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Converter, Convertible} alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Service.ActivityPub.Converter.Address, as: AddressConverter alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
alias Mobilizon.Service.ActivityPub.Converter.Picture, as: PictureConverter alias Mobilizon.Federation.ActivityStream.Converter.Address, as: AddressConverter
alias Mobilizon.Service.ActivityPub.Converter.Utils, as: ConverterUtils alias Mobilizon.Federation.ActivityStream.Converter.Picture, as: PictureConverter
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
require Logger require Logger
@behaviour Converter @behaviour Converter
defimpl Convertible, for: EventModel do defimpl Convertible, for: EventModel do
alias Mobilizon.Service.ActivityPub.Converter.Event, as: EventConverter alias Mobilizon.Federation.ActivityStream.Converter.Event, as: EventConverter
defdelegate model_to_as(event), to: EventConverter defdelegate model_to_as(event), to: EventConverter
end end
@ -177,7 +178,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Event do
@spec do_get_address(map) :: integer | nil @spec do_get_address(map) :: integer | nil
defp do_get_address(map) do defp do_get_address(map) do
map = Mobilizon.Service.ActivityPub.Converter.Address.as_to_model_data(map) map = AddressConverter.as_to_model_data(map)
case Addresses.create_address(map) do case Addresses.create_address(map) do
{:ok, %Address{id: address_id}} -> {:ok, %Address{id: address_id}} ->

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Flag do defmodule Mobilizon.Federation.ActivityStream.Converter.Flag do
@moduledoc """ @moduledoc """
Flag converter. Flag converter.
@ -13,14 +13,14 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Flag do
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.Event alias Mobilizon.Events.Event
alias Mobilizon.Reports.Report alias Mobilizon.Reports.Report
alias Mobilizon.Service.ActivityPub.Converter
alias Mobilizon.Service.ActivityPub.Convertible alias Mobilizon.Federation.ActivityPub.Relay
alias Mobilizon.Service.ActivityPub.Relay alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
@behaviour Converter @behaviour Converter
defimpl Convertible, for: Report do defimpl Convertible, for: Report do
alias Mobilizon.Service.ActivityPub.Converter.Flag, as: FlagConverter alias Mobilizon.Federation.ActivityStream.Converter.Flag, as: FlagConverter
defdelegate model_to_as(report), to: FlagConverter defdelegate model_to_as(report), to: FlagConverter
end end

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Follower do defmodule Mobilizon.Federation.ActivityStream.Converter.Follower do
@moduledoc """ @moduledoc """
Participant converter. Participant converter.
@ -6,13 +6,14 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Follower do
internal one, and back. internal one, and back.
""" """
alias Mobilizon.Actors.Actor
alias Mobilizon.Actors.Follower, as: FollowerModel alias Mobilizon.Actors.Follower, as: FollowerModel
alias Mobilizon.Service.ActivityPub.Convertible alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.Actors.Actor
defimpl Convertible, for: FollowerModel do defimpl Convertible, for: FollowerModel do
alias Mobilizon.Service.ActivityPub.Converter.Follower, as: FollowerConverter alias Mobilizon.Federation.ActivityStream.Converter.Follower,
as: FollowerConverter
defdelegate model_to_as(follower), to: FollowerConverter defdelegate model_to_as(follower), to: FollowerConverter
end end

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Participant do defmodule Mobilizon.Federation.ActivityStream.Converter.Participant do
@moduledoc """ @moduledoc """
Participant converter. Participant converter.
@ -8,10 +8,10 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Participant do
alias Mobilizon.Events.Participant, as: ParticipantModel alias Mobilizon.Events.Participant, as: ParticipantModel
alias Mobilizon.Service.ActivityPub.Convertible alias Mobilizon.Federation.ActivityStream.Convertible
defimpl Convertible, for: ParticipantModel do defimpl Convertible, for: ParticipantModel do
alias Mobilizon.Service.ActivityPub.Converter.Participant, as: ParticipantConverter alias Mobilizon.Federation.ActivityStream.Converter.Participant, as: ParticipantConverter
defdelegate model_to_as(participant), to: ParticipantConverter defdelegate model_to_as(participant), to: ParticipantConverter
end end

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Picture do defmodule Mobilizon.Federation.ActivityStream.Converter.Picture do
@moduledoc """ @moduledoc """
Picture converter. Picture converter.
@ -33,13 +33,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Picture do
) )
when is_bitstring(picture_url) do when is_bitstring(picture_url) do
with {:ok, %HTTPoison.Response{body: body}} <- HTTPoison.get(picture_url), with {:ok, %HTTPoison.Response{body: body}} <- HTTPoison.get(picture_url),
{:ok, {:ok, %{name: name, url: url, content_type: content_type, size: size}} <-
%{
name: name,
url: url,
content_type: content_type,
size: size
}} <-
MobilizonWeb.Upload.store(%{body: body, name: name}), MobilizonWeb.Upload.store(%{body: body, name: name}),
{:picture_exists, nil} <- {:picture_exists, Mobilizon.Media.get_picture_by_url(url)} do {:picture_exists, nil} <- {:picture_exists, Mobilizon.Media.get_picture_by_url(url)} do
Mobilizon.Media.create_picture(%{ Mobilizon.Media.create_picture(%{

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Tombstone do defmodule Mobilizon.Federation.ActivityStream.Converter.Tombstone do
@moduledoc """ @moduledoc """
Comment converter. Comment converter.
@ -6,14 +6,15 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Tombstone do
""" """
alias Mobilizon.Tombstone, as: TombstoneModel alias Mobilizon.Tombstone, as: TombstoneModel
alias Mobilizon.Service.ActivityPub.{Converter, Convertible}
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
require Logger require Logger
@behaviour Converter @behaviour Converter
defimpl Convertible, for: TombstoneModel do defimpl Convertible, for: TombstoneModel do
alias Mobilizon.Service.ActivityPub.Converter.Tombstone, as: TombstoneConverter alias Mobilizon.Federation.ActivityStream.Converter.Tombstone, as: TombstoneConverter
defdelegate model_to_as(comment), to: TombstoneConverter defdelegate model_to_as(comment), to: TombstoneConverter
end end

View File

@ -1,14 +1,16 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Utils do defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
@moduledoc """ @moduledoc """
Various utils for converters Various utils for converters.
""" """
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.Tag alias Mobilizon.Events.Tag
alias Mobilizon.Mention alias Mobilizon.Mention
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
alias Mobilizon.Federation.ActivityPub
require Logger require Logger
@spec fetch_tags([String.t()]) :: [Tag.t()] @spec fetch_tags([String.t()]) :: [Tag.t()]
@ -27,9 +29,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Utils do
end end
def fetch_address(%{id: id}) do def fetch_address(%{id: id}) do
with {id, ""} <- Integer.parse(id) do with {id, ""} <- Integer.parse(id), do: %{id: id}
%{id: id}
end
end end
def fetch_address(address) when is_map(address) do def fetch_address(address) when is_map(address) do

View File

@ -1,4 +1,4 @@
defprotocol Mobilizon.Service.ActivityPub.Convertible do defprotocol Mobilizon.Federation.ActivityStream.Convertible do
@moduledoc """ @moduledoc """
Convertible protocol. Convertible protocol.
""" """

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/signature.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/signature.ex
defmodule Mobilizon.Service.HTTPSignatures.Signature do defmodule Mobilizon.Federation.HTTPSignatures.Signature do
@moduledoc """ @moduledoc """
Adapter for the `HTTPSignatures` lib that handles signing and providing public keys to verify HTTPSignatures Adapter for the `HTTPSignatures` lib that handles signing and providing public keys to verify HTTPSignatures
""" """
@ -11,7 +11,8 @@ defmodule Mobilizon.Service.HTTPSignatures.Signature do
@behaviour HTTPSignatures.Adapter @behaviour HTTPSignatures.Adapter
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Federation.ActivityPub
require Logger require Logger
@ -111,6 +112,6 @@ defmodule Mobilizon.Service.HTTPSignatures.Signature do
def generate_request_target(method, path), do: "#{method} #{path}" def generate_request_target(method, path), do: "#{method} #{path}"
def build_digest(body) do def build_digest(body) do
"SHA-256=" <> (:crypto.hash(:sha256, body) |> Base.encode64()) "SHA-256=#{:sha256 |> :crypto.hash(body) |> Base.encode64()}"
end end
end end

View File

@ -3,16 +3,16 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/web_finger/web_finger.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/web_finger/web_finger.ex
defmodule Mobilizon.Service.WebFinger do defmodule Mobilizon.Federation.WebFinger do
@moduledoc """ @moduledoc """
# WebFinger Performs the WebFinger requests and responses (JSON only).
Performs the WebFinger requests and responses (JSON only)
""" """
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Service.XmlBuilder
alias Mobilizon.Federation.WebFinger.XmlBuilder
require Jason require Jason
require Logger require Logger

View File

@ -3,16 +3,13 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/xml_builder.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/xml_builder.ex
defmodule Mobilizon.Service.XmlBuilder do defmodule Mobilizon.Federation.WebFinger.XmlBuilder do
@moduledoc """ @moduledoc """
XML Builder. Builds XRD for WebFinger host_meta.
Needed to build XRD for webfinger host_meta
""" """
def to_xml({tag, attributes, content}) do def to_xml({tag, attributes, content}) do
open_tag = make_open_tag(tag, attributes) open_tag = make_open_tag(tag, attributes)
content_xml = to_xml(content) content_xml = to_xml(content)
"<#{open_tag}>#{content_xml}</#{tag}>" "<#{open_tag}>#{content_xml}</#{tag}>"
@ -26,28 +23,22 @@ defmodule Mobilizon.Service.XmlBuilder do
def to_xml({tag, content}), do: to_xml({tag, %{}, content}) def to_xml({tag, content}), do: to_xml({tag, %{}, content})
def to_xml(content) when is_binary(content) do def to_xml(content) when is_binary(content), do: to_string(content)
to_string(content)
end
def to_xml(content) when is_list(content) do def to_xml(content) when is_list(content) do
for element <- content do content
to_xml(element) |> Enum.map(&to_xml/1)
end
|> Enum.join() |> Enum.join()
end end
def to_xml(%NaiveDateTime{} = time) do def to_xml(%NaiveDateTime{} = time), do: NaiveDateTime.to_iso8601(time)
NaiveDateTime.to_iso8601(time)
end
def to_doc(content), do: ~s(<?xml version="1.0" encoding="UTF-8"?>) <> to_xml(content) def to_doc(content), do: ~s(<?xml version="1.0" encoding="UTF-8"?>) <> to_xml(content)
defp make_open_tag(tag, attributes) do defp make_open_tag(tag, attributes) do
attributes_string = attributes_string =
for {attribute, value} <- attributes do attributes
"#{attribute}=\"#{value}\"" |> Enum.map(fn {attribute, value} -> "#{attribute}=\"#{value}\"" end)
end
|> Enum.join(" ") |> Enum.join(" ")
[tag, attributes_string] |> Enum.join(" ") |> String.trim() [tag, attributes_string] |> Enum.join(" ") |> String.trim()

View File

@ -23,7 +23,7 @@ defmodule Mix.Tasks.Mobilizon.Relay do
use Mix.Task use Mix.Task
alias Mix.Tasks.Mobilizon.Common alias Mix.Tasks.Mobilizon.Common
alias Mobilizon.Service.ActivityPub.Relay alias Mobilizon.Federation.ActivityPub.Relay
@shortdoc "Manages remote relays" @shortdoc "Manages remote relays"
def run(["follow", target]) do def run(["follow", target]) do

View File

@ -7,11 +7,12 @@ defmodule Mix.Tasks.Mobilizon.SetupSearch do
use Mix.Task use Mix.Task
alias Mobilizon.Service.Workers.BuildSearchWorker
alias Mobilizon.Storage.Repo
alias Mobilizon.Events.Event
import Ecto.Query import Ecto.Query
alias Mobilizon.Events.Event
alias Mobilizon.Service.Workers
alias Mobilizon.Storage.Repo
require Logger require Logger
@shortdoc "Insert search data" @shortdoc "Insert search data"
@ -30,7 +31,7 @@ defmodule Mix.Tasks.Mobilizon.SetupSearch do
end end
defp insert_search_event([%Event{url: url} = event | events], nb_events) do defp insert_search_event([%Event{url: url} = event | events], nb_events) do
case BuildSearchWorker.insert_search_event(event) do case Workers.BuildSearch.insert_search_event(event) do
{:ok, _} -> {:ok, _} ->
Logger.debug("Added event #{url} to the search") Logger.debug("Added event #{url} to the search")

View File

@ -15,6 +15,7 @@ defmodule Mobilizon do
import Cachex.Spec import Cachex.Spec
alias Mobilizon.Config alias Mobilizon.Config
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Service.Export.{Feed, ICalendar} alias Mobilizon.Service.Export.{Feed, ICalendar}
@name Mix.Project.config()[:name] @name Mix.Project.config()[:name]
@ -41,7 +42,7 @@ defmodule Mobilizon do
{Oban, Application.get_env(:mobilizon, Oban)}, {Oban, Application.get_env(:mobilizon, Oban)},
# workers # workers
Guardian.DB.Token.SweeperServer, Guardian.DB.Token.SweeperServer,
Mobilizon.Service.Federator, ActivityPub.Federator,
cachex_spec(:feed, 2500, 60, 60, &Feed.create_cache/1), cachex_spec(:feed, 2500, 60, 60, &Feed.create_cache/1),
cachex_spec(:ics, 2500, 60, 60, &ICalendar.create_cache/1), cachex_spec(:ics, 2500, 60, 60, &ICalendar.create_cache/1),
cachex_spec(:statistics, 10, 60, 60), cachex_spec(:statistics, 10, 60, 60),
@ -94,7 +95,7 @@ defmodule Mobilizon do
defp internal_actor() do defp internal_actor() do
%{ %{
id: :internal_actor_init, id: :internal_actor_init,
start: {Task, :start_link, [&Mobilizon.Service.ActivityPub.Relay.init/0]}, start: {Task, :start_link, [&ActivityPub.Relay.init/0]},
restart: :temporary restart: :temporary
} }
end end

View File

@ -11,9 +11,10 @@ defmodule Mobilizon.Actors do
alias Mobilizon.Actors.{Actor, Bot, Follower, Member} alias Mobilizon.Actors.{Actor, Bot, Follower, Member}
alias Mobilizon.{Crypto, Events} alias Mobilizon.{Crypto, Events}
alias Mobilizon.Media.File alias Mobilizon.Media.File
alias Mobilizon.Service.Workers
alias Mobilizon.Storage.{Page, Repo} alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Service.Workers.BackgroundWorker
alias Mobilizon.Service.ActivityPub alias Mobilizon.Federation.ActivityPub
require Logger require Logger
@ -228,7 +229,7 @@ defmodule Mobilizon.Actors do
end end
def delete_actor(%Actor{} = actor) do def delete_actor(%Actor{} = actor) do
BackgroundWorker.enqueue("delete_actor", %{"actor_id" => actor.id}) Workers.Background.enqueue("delete_actor", %{"actor_id" => actor.id})
end end
@doc """ @doc """

View File

@ -1,11 +1,3 @@
import EctoEnum
defenum(Mobilizon.Admin.ActionLogAction, [
"update",
"create",
"delete"
])
defmodule Mobilizon.Admin.ActionLog do defmodule Mobilizon.Admin.ActionLog do
@moduledoc """ @moduledoc """
Represents an action log entity. Represents an action log entity.

View File

@ -4,9 +4,19 @@ defmodule Mobilizon.Admin do
""" """
import Ecto.Query import Ecto.Query
import EctoEnum
alias Mobilizon.Actors.Actor
alias Mobilizon.{Admin, Users}
alias Mobilizon.Admin.ActionLog alias Mobilizon.Admin.ActionLog
alias Mobilizon.Storage.{Page, Repo} alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.User
defenum(ActionLogAction, [
"update",
"create",
"delete"
])
@doc """ @doc """
Creates a action_log. Creates a action_log.
@ -28,8 +38,37 @@ defmodule Mobilizon.Admin do
|> Repo.all() |> Repo.all()
end end
@doc """
Log an admin action
"""
@spec log_action(Actor.t(), String.t(), String.t()) :: {:ok, ActionLog.t()}
def log_action(%Actor{user_id: user_id, id: actor_id}, action, target) do
with %User{role: role} <- Users.get_user!(user_id),
{:role, true} <- {:role, role in [:administrator, :moderator]},
{:ok, %ActionLog{} = create_action_log} <-
Admin.create_action_log(%{
"actor_id" => actor_id,
"target_type" => to_string(target.__struct__),
"target_id" => target.id,
"action" => action,
"changes" => stringify_struct(target)
}) do
{:ok, create_action_log}
end
end
@spec list_action_logs_query :: Ecto.Query.t() @spec list_action_logs_query :: Ecto.Query.t()
defp list_action_logs_query do defp list_action_logs_query do
from(r in ActionLog, preload: [:actor], order_by: [desc: :id]) from(r in ActionLog, preload: [:actor], order_by: [desc: :id])
end end
defp stringify_struct(%_{} = struct) do
association_fields = struct.__struct__.__schema__(:associations)
struct
|> Map.from_struct()
|> Map.drop(association_fields ++ [:__meta__])
end
defp stringify_struct(struct), do: struct
end end

View File

@ -7,13 +7,13 @@ defmodule Mobilizon.Events do
import Ecto.Query import Ecto.Query
import EctoEnum import EctoEnum
alias Ecto.{Multi, Changeset}
import Mobilizon.Storage.Ecto import Mobilizon.Storage.Ecto
alias Ecto.{Multi, Changeset}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Addresses.Address alias Mobilizon.Addresses.Address
alias Mobilizon.Service.Workers.BuildSearchWorker
alias Mobilizon.Events.{ alias Mobilizon.Events.{
Comment, Comment,
@ -27,9 +27,12 @@ defmodule Mobilizon.Events do
Track Track
} }
alias Mobilizon.Service.Workers
alias Mobilizon.Storage.{Page, Repo} alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias MobilizonWeb.Email
defenum(EventVisibility, :event_visibility, [ defenum(EventVisibility, :event_visibility, [
:public, :public,
:unlisted, :unlisted,
@ -264,7 +267,7 @@ defmodule Mobilizon.Events do
with {:ok, %{insert: %Event{} = event}} <- do_create_event(attrs), with {:ok, %{insert: %Event{} = event}} <- do_create_event(attrs),
%Event{} = event <- Repo.preload(event, @event_preloads) do %Event{} = event <- Repo.preload(event, @event_preloads) do
unless event.draft, unless event.draft,
do: BuildSearchWorker.enqueue(:insert_search_event, %{"event_id" => event.id}) do: Workers.BuildSearch.enqueue(:insert_search_event, %{"event_id" => event.id})
{:ok, event} {:ok, event}
else else
@ -308,10 +311,7 @@ defmodule Mobilizon.Events do
Event.update_changeset(Repo.preload(old_event, :tags), attrs), Event.update_changeset(Repo.preload(old_event, :tags), attrs),
{:ok, %{update: %Event{} = new_event}} <- {:ok, %{update: %Event{} = new_event}} <-
Multi.new() Multi.new()
|> Multi.update( |> Multi.update(:update, changeset)
:update,
changeset
)
|> Multi.run(:write, fn _repo, %{update: %Event{draft: draft} = event} -> |> Multi.run(:write, fn _repo, %{update: %Event{draft: draft} = event} ->
with {:was_draft, true} <- {:was_draft, old_draft == true && draft == false}, with {:was_draft, true} <- {:was_draft, old_draft == true && draft == false},
{:ok, %Participant{} = participant} <- {:ok, %Participant{} = participant} <-
@ -332,14 +332,14 @@ defmodule Mobilizon.Events do
|> Repo.transaction() do |> Repo.transaction() do
Cachex.del(:ics, "event_#{new_event.uuid}") Cachex.del(:ics, "event_#{new_event.uuid}")
Mobilizon.Service.Events.Tool.calculate_event_diff_and_send_notifications( Email.Event.calculate_event_diff_and_send_notifications(
old_event, old_event,
new_event, new_event,
changes changes
) )
unless new_event.draft, unless new_event.draft,
do: BuildSearchWorker.enqueue(:update_search_event, %{"event_id" => new_event.id}) do: Workers.BuildSearch.enqueue(:update_search_event, %{"event_id" => new_event.id})
{:ok, Repo.preload(new_event, @event_preloads)} {:ok, Repo.preload(new_event, @event_preloads)}
end end

View File

@ -31,7 +31,7 @@ defmodule Mobilizon.Tombstone do
|> validate_required(@required_attrs) |> validate_required(@required_attrs)
end end
@spec create_tombstone(map()) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()} @spec create_tombstone(map) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
def create_tombstone(attrs) do def create_tombstone(attrs) do
%__MODULE__{} %__MODULE__{}
|> changeset(attrs) |> changeset(attrs)

View File

@ -0,0 +1,9 @@
defmodule Mobilizon.Users.Guards do
@moduledoc """
Guards for users
"""
defguard is_admin(role) when is_atom(role) and role == :administrator
defguard is_moderator(role) when is_atom(role) and role in [:administrator, :moderator]
end

View File

@ -10,9 +10,10 @@ defmodule Mobilizon.Users.User do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Crypto alias Mobilizon.Crypto
alias Mobilizon.Events.FeedToken alias Mobilizon.Events.FeedToken
alias Mobilizon.Service.EmailChecker
alias Mobilizon.Users.UserRole alias Mobilizon.Users.UserRole
alias MobilizonWeb.Email
@type t :: %__MODULE__{ @type t :: %__MODULE__{
email: String.t(), email: String.t(),
password_hash: String.t(), password_hash: String.t(),
@ -176,7 +177,7 @@ defmodule Mobilizon.Users.User do
case changeset do case changeset do
%Ecto.Changeset{valid?: true, changes: %{email: email}} -> %Ecto.Changeset{valid?: true, changes: %{email: email}} ->
case EmailChecker.valid?(email) do case Email.Checker.valid?(email) do
false -> false ->
add_error(changeset, :email, "Email doesn't fit required format") add_error(changeset, :email, "Email doesn't fit required format")

View File

@ -13,6 +13,8 @@ defmodule Mobilizon.Users do
alias Mobilizon.Storage.{Page, Repo} alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias MobilizonWeb.Auth
@type tokens :: %{ @type tokens :: %{
required(:access_token) => String.t(), required(:access_token) => String.t(),
required(:refresh_token) => String.t() required(:refresh_token) => String.t()
@ -247,7 +249,7 @@ defmodule Mobilizon.Users do
@spec generate_access_token(User.t()) :: {:ok, String.t()} @spec generate_access_token(User.t()) :: {:ok, String.t()}
def generate_access_token(user) do def generate_access_token(user) do
with {:ok, access_token, _claims} <- with {:ok, access_token, _claims} <-
MobilizonWeb.Guardian.encode_and_sign(user, %{}, token_type: "access") do Auth.Guardian.encode_and_sign(user, %{}, token_type: "access") do
{:ok, access_token} {:ok, access_token}
end end
end end
@ -258,7 +260,7 @@ defmodule Mobilizon.Users do
@spec generate_refresh_token(User.t()) :: {:ok, String.t()} @spec generate_refresh_token(User.t()) :: {:ok, String.t()}
def generate_refresh_token(user) do def generate_refresh_token(user) do
with {:ok, refresh_token, _claims} <- with {:ok, refresh_token, _claims} <-
MobilizonWeb.Guardian.encode_and_sign(user, %{}, token_type: "refresh") do Auth.Guardian.encode_and_sign(user, %{}, token_type: "refresh") do
{:ok, refresh_token} {:ok, refresh_token}
end end
end end

View File

@ -3,8 +3,9 @@ defmodule MobilizonWeb.API.Comments do
API for Comments. API for Comments.
""" """
alias Mobilizon.Events.Comment alias Mobilizon.Events.Comment
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Activity alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Activity
@doc """ @doc """
Create a comment Create a comment

View File

@ -5,9 +5,9 @@ defmodule MobilizonWeb.API.Events do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events.Event alias Mobilizon.Events.Event
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Activity alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Service.ActivityPub.Utils alias Mobilizon.Federation.ActivityPub.{Activity, Utils}
@doc """ @doc """
Create an event Create an event

View File

@ -5,8 +5,9 @@ defmodule MobilizonWeb.API.Follows do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.{Actor, Follower} alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Activity alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Activity
require Logger require Logger

View File

@ -5,8 +5,9 @@ defmodule MobilizonWeb.API.Groups do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Activity alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Activity
@doc """ @doc """
Create a group Create a group

View File

@ -5,7 +5,9 @@ defmodule MobilizonWeb.API.Participations do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events.{Event, Participant} alias Mobilizon.Events.{Event, Participant}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Federation.ActivityPub
alias MobilizonWeb.Email.Participation alias MobilizonWeb.Email.Participation
@spec join(Event.t(), Actor.t()) :: {:ok, Participant.t()} @spec join(Event.t(), Actor.t()) :: {:ok, Participant.t()}

View File

@ -3,16 +3,15 @@ defmodule MobilizonWeb.API.Reports do
API for Reports. API for Reports.
""" """
import Mobilizon.Service.Admin.ActionLogService
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.{Admin, Users}
alias Mobilizon.Reports, as: ReportsAction alias Mobilizon.Reports, as: ReportsAction
alias Mobilizon.Reports.{Note, Report, ReportStatus} alias Mobilizon.Reports.{Note, Report, ReportStatus}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Users
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Activity
@doc """ @doc """
Create a report/flag on an actor, and optionally on an event or on comments. Create a report/flag on an actor, and optionally on an event or on comments.
""" """
@ -33,7 +32,7 @@ defmodule MobilizonWeb.API.Reports do
with {:valid_state, true} <- with {:valid_state, true} <-
{:valid_state, ReportStatus.valid_value?(state)}, {:valid_state, ReportStatus.valid_value?(state)},
{:ok, report} <- ReportsAction.update_report(report, %{"status" => state}), {:ok, report} <- ReportsAction.update_report(report, %{"status" => state}),
{:ok, _} <- log_action(actor, "update", report) do {:ok, _} <- Admin.log_action(actor, "update", report) do
{:ok, report} {:ok, report}
else else
{:valid_state, false} -> {:error, "Unsupported state"} {:valid_state, false} -> {:error, "Unsupported state"}
@ -57,7 +56,7 @@ defmodule MobilizonWeb.API.Reports do
"moderator_id" => moderator_id, "moderator_id" => moderator_id,
"content" => content "content" => content
}), }),
{:ok, _} <- log_action(moderator, "create", note) do {:ok, _} <- Admin.log_action(moderator, "create", note) do
{:ok, note} {:ok, note}
else else
{:role, false} -> {:role, false} ->
@ -78,7 +77,7 @@ defmodule MobilizonWeb.API.Reports do
{:role, true} <- {:role, role in [:administrator, :moderator]}, {:role, true} <- {:role, role in [:administrator, :moderator]},
{:ok, %Note{} = note} <- {:ok, %Note{} = note} <-
Mobilizon.Reports.delete_note(note), Mobilizon.Reports.delete_note(note),
{:ok, _} <- log_action(moderator, "delete", note) do {:ok, _} <- Admin.log_action(moderator, "delete", note) do
{:ok, note} {:ok, note}
else else
{:role, false} -> {:role, false} ->

View File

@ -6,9 +6,10 @@ defmodule MobilizonWeb.API.Search do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.ActorType alias Mobilizon.Actors.ActorType
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Storage.Page alias Mobilizon.Storage.Page
alias Mobilizon.Federation.ActivityPub
require Logger require Logger
@doc """ @doc """

View File

@ -1,10 +1,11 @@
defmodule MobilizonWeb.Context do defmodule MobilizonWeb.Auth.Context do
@moduledoc """ @moduledoc """
Guardian context for MobilizonWeb Guardian context for MobilizonWeb
""" """
@behaviour Plug @behaviour Plug
import Plug.Conn import Plug.Conn
alias Mobilizon.Users.User alias Mobilizon.Users.User
def init(opts) do def init(opts) do
@ -17,8 +18,7 @@ defmodule MobilizonWeb.Context do
context = context =
case Guardian.Plug.current_resource(conn) do case Guardian.Plug.current_resource(conn) do
%User{} = user -> %User{} = user ->
context Map.put(context, :current_user, user)
|> Map.put(:current_user, user)
nil -> nil ->
context context

View File

@ -1,4 +1,4 @@
defmodule MobilizonWeb.AuthErrorHandler do defmodule MobilizonWeb.Auth.ErrorHandler do
@moduledoc """ @moduledoc """
In case we have an auth error In case we have an auth error
""" """

View File

@ -1,7 +1,8 @@
defmodule MobilizonWeb.Guardian do defmodule MobilizonWeb.Auth.Guardian do
@moduledoc """ @moduledoc """
Handles the JWT tokens encoding and decoding Handles the JWT tokens encoding and decoding
""" """
use Guardian, use Guardian,
otp_app: :mobilizon, otp_app: :mobilizon,
permissions: %{ permissions: %{
@ -11,6 +12,7 @@ defmodule MobilizonWeb.Guardian do
alias Mobilizon.Users alias Mobilizon.Users
alias Mobilizon.Users.User alias Mobilizon.Users.User
require Logger require Logger
def subject_for_token(%User{} = user, _claims) do def subject_for_token(%User{} = user, _claims) do

View File

@ -1,14 +1,14 @@
defmodule MobilizonWeb.AuthPipeline do defmodule MobilizonWeb.Auth.Pipeline do
@moduledoc """ @moduledoc """
Handles the app sessions Handles the app sessions
""" """
use Guardian.Plug.Pipeline, use Guardian.Plug.Pipeline,
otp_app: :mobilizon, otp_app: :mobilizon,
module: MobilizonWeb.Guardian, module: MobilizonWeb.Auth.Guardian,
error_handler: MobilizonWeb.AuthErrorHandler error_handler: MobilizonWeb.Auth.ErrorHandler
plug(Guardian.Plug.VerifyHeader, realm: "Bearer") plug(Guardian.Plug.VerifyHeader, realm: "Bearer")
plug(Guardian.Plug.LoadResource, allow_blank: true) plug(Guardian.Plug.LoadResource, allow_blank: true)
plug(MobilizonWeb.Context) plug(MobilizonWeb.Auth.Context)
end end

View File

@ -1,14 +1,16 @@
defmodule MobilizonWeb.Cache.ActivityPub do defmodule MobilizonWeb.Cache.ActivityPub do
@moduledoc """ @moduledoc """
The ActivityPub related functions. ActivityPub related cache.
""" """
alias Mobilizon.{Actors, Events, Service, Tombstone} alias Mobilizon.{Actors, Events, Tombstone}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events.{Comment, Event} alias Mobilizon.Events.{Comment, Event}
alias Service.ActivityPub
alias MobilizonWeb.Router.Helpers, as: Routes alias Mobilizon.Federation.ActivityPub.Relay
alias MobilizonWeb.Endpoint alias MobilizonWeb.Endpoint
alias MobilizonWeb.Router.Helpers, as: Routes
@cache :activity_pub @cache :activity_pub
@ -73,6 +75,6 @@ defmodule MobilizonWeb.Cache.ActivityPub do
""" """
@spec get_relay :: {:commit, Actor.t()} | {:ignore, nil} @spec get_relay :: {:commit, Actor.t()} | {:ignore, nil}
def get_relay do def get_relay do
Cachex.fetch(@cache, "relay_actor", &ActivityPub.Relay.get_actor/0) Cachex.fetch(@cache, "relay_actor", &Relay.get_actor/0)
end end
end end

View File

@ -8,7 +8,7 @@ defmodule MobilizonWeb.GraphQLSocket do
def connect(%{"token" => token}, socket) do def connect(%{"token" => token}, socket) do
with {:ok, authed_socket} <- with {:ok, authed_socket} <-
Guardian.Phoenix.Socket.authenticate(socket, MobilizonWeb.Guardian, token), Guardian.Phoenix.Socket.authenticate(socket, MobilizonWeb.Auth.Guardian, token),
%User{} = user <- Guardian.Phoenix.Socket.current_resource(authed_socket) do %User{} = user <- Guardian.Phoenix.Socket.current_resource(authed_socket) do
authed_socket = authed_socket =
Absinthe.Phoenix.Socket.put_options(socket, Absinthe.Phoenix.Socket.put_options(socket,

View File

@ -6,9 +6,11 @@
defmodule MobilizonWeb.ActivityPubController do defmodule MobilizonWeb.ActivityPubController do
use MobilizonWeb, :controller use MobilizonWeb, :controller
alias Mobilizon.{Actors, Actors.Actor, Config} alias Mobilizon.{Actors, Config}
alias Mobilizon.Service.ActivityPub alias Mobilizon.Actors.Actor
alias Mobilizon.Service.Federator
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Federator
alias MobilizonWeb.ActivityPub.ActorView alias MobilizonWeb.ActivityPub.ActorView
alias MobilizonWeb.Cache alias MobilizonWeb.Cache

View File

@ -7,10 +7,12 @@ defmodule MobilizonWeb.WebFingerController do
@moduledoc """ @moduledoc """
Handles Webfinger requests Handles Webfinger requests
""" """
use MobilizonWeb, :controller use MobilizonWeb, :controller
alias Mobilizon.Federation.WebFinger
plug(MobilizonWeb.Plugs.Federating) plug(MobilizonWeb.Plugs.Federating)
alias Mobilizon.Service.WebFinger
@doc """ @doc """
Provides /.well-known/host-meta Provides /.well-known/host-meta

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.EmailChecker do defmodule MobilizonWeb.Email.Checker do
@moduledoc """ @moduledoc """
Provides a function to test emails against a "not so bad" regex. Provides a function to test emails against a "not so bad" regex.
""" """

View File

@ -9,11 +9,16 @@ defmodule MobilizonWeb.Email.Event do
import MobilizonWeb.Gettext import MobilizonWeb.Gettext
alias Mobilizon.Events.Event
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.Event
alias Mobilizon.Storage.Repo
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias MobilizonWeb.Email alias MobilizonWeb.Email
@important_changes [:title, :begins_on, :ends_on, :status]
@spec event_updated(User.t(), Actor.t(), Event.t(), Event.t(), list(), String.t()) :: @spec event_updated(User.t(), Actor.t(), Event.t(), Event.t(), list(), String.t()) ::
Bamboo.Email.t() Bamboo.Email.t()
def event_updated( def event_updated(
@ -40,4 +45,41 @@ defmodule MobilizonWeb.Email.Event do
|> assign(:subject, subject) |> assign(:subject, subject)
|> render(:event_updated) |> render(:event_updated)
end end
def calculate_event_diff_and_send_notifications(
%Event{} = old_event,
%Event{id: event_id} = event,
changes
) do
important = MapSet.new(@important_changes)
diff =
changes
|> Map.keys()
|> MapSet.new()
|> MapSet.intersection(important)
if MapSet.size(diff) > 0 do
Repo.transaction(fn ->
event_id
|> Events.list_local_emails_user_participants_for_event_query()
|> Repo.stream()
|> Enum.to_list()
|> Enum.each(
&send_notification_for_event_update_to_participant(&1, old_event, event, diff)
)
end)
end
end
defp send_notification_for_event_update_to_participant(
{%Actor{} = actor, %User{locale: locale} = user},
%Event{} = old_event,
%Event{} = event,
diff
) do
user
|> Email.Event.event_updated(actor, old_event, event, diff, locale)
|> Email.Mailer.deliver_later()
end
end end

View File

@ -9,11 +9,14 @@ defmodule MobilizonWeb.Email.User do
import MobilizonWeb.Gettext import MobilizonWeb.Gettext
alias Mobilizon.Config alias Mobilizon.{Config, Crypto, Users}
alias Mobilizon.Storage.Repo
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias MobilizonWeb.Email alias MobilizonWeb.Email
require Logger
@spec confirmation_email(User.t(), String.t()) :: Bamboo.Email.t() @spec confirmation_email(User.t(), String.t()) :: Bamboo.Email.t()
def confirmation_email( def confirmation_email(
%User{email: email, confirmation_token: confirmation_token}, %User{email: email, confirmation_token: confirmation_token},
@ -53,4 +56,108 @@ defmodule MobilizonWeb.Email.User do
|> assign(:subject, subject) |> assign(:subject, subject)
|> render(:password_reset) |> render(:password_reset)
end end
def check_confirmation_token(token) when is_binary(token) do
with %User{} = user <- Users.get_user_by_activation_token(token),
{:ok, %User{} = user} <-
Users.update_user(user, %{
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
"confirmation_sent_at" => nil,
"confirmation_token" => nil
}) do
Logger.info("User #{user.email} has been confirmed")
{:ok, user}
else
_err ->
{:error, :invalid_token}
end
end
def resend_confirmation_email(%User{} = user, locale \\ "en") do
with :ok <- we_can_send_email(user, :confirmation_sent_at),
{:ok, user} <-
Users.update_user(user, %{
"confirmation_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
}) do
send_confirmation_email(user, locale)
Logger.info("Sent confirmation email again to #{user.email}")
{:ok, user.email}
end
end
def send_confirmation_email(%User{} = user, locale \\ "en") do
user
|> Email.User.confirmation_email(locale)
|> Email.Mailer.deliver_later()
end
@doc """
Check that the provided token is correct and update provided password
"""
@spec check_reset_password_token(String.t(), String.t()) :: tuple
def check_reset_password_token(password, token) do
with %User{} = user <- Users.get_user_by_reset_password_token(token),
{:ok, %User{} = user} <-
Repo.update(
User.password_reset_changeset(user, %{
"password" => password,
"reset_password_sent_at" => nil,
"reset_password_token" => nil
})
) do
{:ok, user}
else
{:error, %Ecto.Changeset{errors: [password: {"registration.error.password_too_short", _}]}} ->
{:error,
"The password you have choosen is too short. Please make sure your password contains at least 6 charaters."}
_err ->
{:error,
"The token you provided is invalid. Make sure that the URL is exactly the one provided inside the email you got."}
end
end
@doc """
Send the email reset password, if it's not too soon since the last send
"""
@spec send_password_reset_email(User.t(), String.t()) :: tuple
def send_password_reset_email(%User{} = user, locale \\ "en") do
with :ok <- we_can_send_email(user, :reset_password_sent_at),
{:ok, %User{} = user_updated} <-
Repo.update(
User.send_password_reset_changeset(user, %{
"reset_password_token" => Crypto.random_string(30),
"reset_password_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
})
) do
mail =
user_updated
|> Email.User.reset_password_email(locale)
|> Email.Mailer.deliver_later()
{:ok, mail}
else
{:error, reason} -> {:error, reason}
end
end
@spec we_can_send_email(User.t(), atom) :: :ok | {:error, :email_too_soon}
defp we_can_send_email(%User{} = user, key) do
case Map.get(user, key) do
nil ->
:ok
_ ->
case Timex.before?(
Timex.shift(Map.get(user, key), hours: 1),
DateTime.utc_now() |> DateTime.truncate(:second)
) do
true ->
:ok
false ->
{:error, :email_too_soon}
end
end
end
end end

View File

@ -7,6 +7,7 @@ defmodule MobilizonWeb.Plugs.Federating do
@moduledoc """ @moduledoc """
Restrict ActivityPub routes when not federating Restrict ActivityPub routes when not federating
""" """
import Plug.Conn import Plug.Conn
def init(options) do def init(options) do

View File

@ -3,14 +3,13 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/plugs/http_signature.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/plugs/http_signature.ex
defmodule MobilizonWeb.HTTPSignaturePlug do defmodule MobilizonWeb.Plugs.HTTPSignatures do
@moduledoc """ @moduledoc """
# HTTPSignaturePlug
Plug to check HTTP Signatures on every incoming request Plug to check HTTP Signatures on every incoming request
""" """
import Plug.Conn import Plug.Conn
require Logger require Logger
def init(options) do def init(options) do

View File

@ -7,12 +7,15 @@ defmodule MobilizonWeb.Plugs.MappedSignatureToIdentity do
@moduledoc """ @moduledoc """
Get actor identity from Signature when handing fetches Get actor identity from Signature when handing fetches
""" """
alias Mobilizon.Service.HTTPSignatures.Signature
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub.Utils
alias Mobilizon.Service.ActivityPub
import Plug.Conn import Plug.Conn
alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Utils
alias Mobilizon.Federation.HTTPSignatures.Signature
require Logger require Logger
def init(options), do: options def init(options), do: options

View File

@ -35,8 +35,7 @@ defmodule MobilizonWeb.Plugs.UploadedMedia do
%{query_params: %{"name" => name}} = conn -> %{query_params: %{"name" => name}} = conn ->
name = String.replace(name, "\"", "\\\"") name = String.replace(name, "\"", "\\\"")
conn put_resp_header(conn, "content-disposition", "filename=\"#{name}\"")
|> put_resp_header("content-disposition", "filename=\"#{name}\"")
conn -> conn ->
conn conn
@ -77,11 +76,7 @@ defmodule MobilizonWeb.Plugs.UploadedMedia do
end end
defp get_media(conn, {:url, url}, true, _) do defp get_media(conn, {:url, url}, true, _) do
conn MobilizonWeb.ReverseProxy.call(conn, url, Config.get([Mobilizon.Upload, :proxy_opts], []))
|> MobilizonWeb.ReverseProxy.call(
url,
Config.get([Mobilizon.Upload, :proxy_opts], [])
)
end end
defp get_media(conn, {:url, url}, _, _) do defp get_media(conn, {:url, url}, _, _) do

View File

@ -2,10 +2,12 @@ defmodule MobilizonWeb.Resolvers.Address do
@moduledoc """ @moduledoc """
Handles the comment-related GraphQL calls Handles the comment-related GraphQL calls
""" """
require Logger
alias Mobilizon.Addresses.Address alias Mobilizon.Addresses.Address
alias Mobilizon.Service.Geospatial alias Mobilizon.Service.Geospatial
require Logger
@doc """ @doc """
Search an address Search an address
""" """

View File

@ -11,10 +11,11 @@ defmodule MobilizonWeb.Resolvers.Admin do
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.{Event, Comment} alias Mobilizon.Events.{Event, Comment}
alias Mobilizon.Reports.{Note, Report} alias Mobilizon.Reports.{Note, Report}
alias Mobilizon.Service.Statistics
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias Mobilizon.Service.Statistics
alias Mobilizon.Storage.Page alias Mobilizon.Storage.Page
alias Mobilizon.Service.ActivityPub.Relay
alias Mobilizon.Federation.ActivityPub.Relay
def list_action_logs( def list_action_logs(
_parent, _parent,

View File

@ -3,14 +3,13 @@ defmodule MobilizonWeb.Resolvers.Comment do
Handles the comment-related GraphQL calls. Handles the comment-related GraphQL calls.
""" """
alias Mobilizon.{Actors, Admin, Events}
alias Mobilizon.Actors.Actor
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.Comment, as: CommentModel alias Mobilizon.Events.Comment, as: CommentModel
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias Mobilizon.Actors.Actor
alias Mobilizon.Actors
alias MobilizonWeb.API.Comments alias MobilizonWeb.API.Comments
import Mobilizon.Service.Admin.ActionLogService
require Logger require Logger
@ -48,7 +47,7 @@ defmodule MobilizonWeb.Resolvers.Comment do
role in [:moderator, :administrator] -> role in [:moderator, :administrator] ->
with {:ok, res} <- do_delete_comment(comment), with {:ok, res} <- do_delete_comment(comment),
%Actor{} = actor <- Actors.get_actor(actor_id) do %Actor{} = actor <- Actors.get_actor(actor_id) do
log_action(actor, "delete", comment) Admin.log_action(actor, "delete", comment)
{:ok, res} {:ok, res}
end end

View File

@ -3,9 +3,10 @@ defmodule MobilizonWeb.Resolvers.Config do
Handles the config-related GraphQL calls. Handles the config-related GraphQL calls.
""" """
alias Mobilizon.Config
alias Geolix.Adapter.MMDB2.Record.{Country, Location} alias Geolix.Adapter.MMDB2.Record.{Country, Location}
alias Mobilizon.Config
@doc """ @doc """
Gets config. Gets config.
""" """

View File

@ -3,15 +3,13 @@ defmodule MobilizonWeb.Resolvers.Event do
Handles the event-related GraphQL calls. Handles the event-related GraphQL calls.
""" """
import Mobilizon.Service.Admin.ActionLogService alias Mobilizon.{Actors, Admin, Events}
alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.{Event, Participant, EventParticipantStats} alias Mobilizon.Events.{Event, Participant, EventParticipantStats}
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias Mobilizon.Federation.ActivityPub.Activity
alias MobilizonWeb.API alias MobilizonWeb.API
alias MobilizonWeb.Resolvers.Person alias MobilizonWeb.Resolvers.Person
@ -342,7 +340,7 @@ defmodule MobilizonWeb.Resolvers.Event do
role in [:moderator, :administrator] -> role in [:moderator, :administrator] ->
with {:ok, res} <- do_delete_event(event, !is_local), with {:ok, res} <- do_delete_event(event, !is_local),
%Actor{} = actor <- Actors.get_actor(actor_id) do %Actor{} = actor <- Actors.get_actor(actor_id) do
log_action(actor, "delete", event) Admin.log_action(actor, "delete", event)
{:ok, res} {:ok, res}
end end

View File

@ -5,9 +5,10 @@ defmodule MobilizonWeb.Resolvers.Group do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.{Actor, Member} alias Mobilizon.Actors.{Actor, Member}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias Mobilizon.Federation.ActivityPub
alias MobilizonWeb.API alias MobilizonWeb.API
alias MobilizonWeb.Resolvers.Person alias MobilizonWeb.Resolvers.Person

View File

@ -7,10 +7,11 @@ defmodule MobilizonWeb.Resolvers.Person do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.Participant alias Mobilizon.Events.Participant
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Users alias Mobilizon.Users
alias Mobilizon.Users.User alias Mobilizon.Users.User
alias Mobilizon.Federation.ActivityPub
@doc """ @doc """
Get a person Get a person
""" """

View File

@ -7,9 +7,10 @@ defmodule MobilizonWeb.Resolvers.User do
alias Mobilizon.{Actors, Config, Users, Events} alias Mobilizon.{Actors, Config, Users, Events}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Service.Users.{Activation, ResetPassword}
alias Mobilizon.Users.User
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
alias Mobilizon.Users.User
alias MobilizonWeb.{Auth, Email}
require Logger require Logger
@ -93,9 +94,9 @@ defmodule MobilizonWeb.Resolvers.User do
}, },
_context _context
) do ) do
with {:ok, user, _claims} <- MobilizonWeb.Guardian.resource_from_token(refresh_token), with {:ok, user, _claims} <- Auth.Guardian.resource_from_token(refresh_token),
{:ok, _old, {exchanged_token, _claims}} <- {:ok, _old, {exchanged_token, _claims}} <-
MobilizonWeb.Guardian.exchange(refresh_token, ["access", "refresh"], "access"), Auth.Guardian.exchange(refresh_token, ["access", "refresh"], "access"),
{:ok, refresh_token} <- Users.generate_refresh_token(user) do {:ok, refresh_token} <- Users.generate_refresh_token(user) do
{:ok, %{access_token: exchanged_token, refresh_token: refresh_token}} {:ok, %{access_token: exchanged_token, refresh_token: refresh_token}}
else else
@ -118,7 +119,7 @@ defmodule MobilizonWeb.Resolvers.User do
def create_user(_parent, args, _resolution) do def create_user(_parent, args, _resolution) do
with :registration_ok <- check_registration_config(args), with :registration_ok <- check_registration_config(args),
{:ok, %User{} = user} <- Users.register(args) do {:ok, %User{} = user} <- Users.register(args) do
Activation.send_confirmation_email(user, Map.get(args, :locale, "en")) Email.User.send_confirmation_email(user, Map.get(args, :locale, "en"))
{:ok, user} {:ok, user}
else else
:registration_closed -> :registration_closed ->
@ -161,7 +162,7 @@ defmodule MobilizonWeb.Resolvers.User do
""" """
def validate_user(_parent, %{token: token}, _resolution) do def validate_user(_parent, %{token: token}, _resolution) do
with {:check_confirmation_token, {:ok, %User{} = user}} <- with {:check_confirmation_token, {:ok, %User{} = user}} <-
{:check_confirmation_token, Activation.check_confirmation_token(token)}, {:check_confirmation_token, Email.User.check_confirmation_token(token)},
{:get_actor, actor} <- {:get_actor, Users.get_actor_for_user(user)}, {:get_actor, actor} <- {:get_actor, Users.get_actor_for_user(user)},
{:ok, %{access_token: access_token, refresh_token: refresh_token}} <- {:ok, %{access_token: access_token, refresh_token: refresh_token}} <-
Users.generate_tokens(user) do Users.generate_tokens(user) do
@ -187,7 +188,7 @@ defmodule MobilizonWeb.Resolvers.User do
with {:ok, %User{locale: locale} = user} <- with {:ok, %User{locale: locale} = user} <-
Users.get_user_by_email(Map.get(args, :email), false), Users.get_user_by_email(Map.get(args, :email), false),
{:ok, email} <- {:ok, email} <-
Activation.resend_confirmation_email(user, Map.get(args, :locale, locale)) do Email.User.resend_confirmation_email(user, Map.get(args, :locale, locale)) do
{:ok, email} {:ok, email}
else else
{:error, :user_not_found} -> {:error, :user_not_found} ->
@ -205,7 +206,7 @@ defmodule MobilizonWeb.Resolvers.User do
with email <- Map.get(args, :email), with email <- Map.get(args, :email),
{:ok, %User{locale: locale} = user} <- Users.get_user_by_email(email, true), {:ok, %User{locale: locale} = user} <- Users.get_user_by_email(email, true),
{:ok, %Bamboo.Email{} = _email_html} <- {:ok, %Bamboo.Email{} = _email_html} <-
ResetPassword.send_password_reset_email(user, Map.get(args, :locale, locale)) do Email.User.send_password_reset_email(user, Map.get(args, :locale, locale)) do
{:ok, email} {:ok, email}
else else
{:error, :user_not_found} -> {:error, :user_not_found} ->
@ -222,7 +223,7 @@ defmodule MobilizonWeb.Resolvers.User do
""" """
def reset_password(_parent, %{password: password, token: token}, _resolution) do def reset_password(_parent, %{password: password, token: token}, _resolution) do
with {:ok, %User{} = user} <- with {:ok, %User{} = user} <-
ResetPassword.check_reset_password_token(password, token), Email.User.check_reset_password_token(password, token),
{:ok, %{access_token: access_token, refresh_token: refresh_token}} <- {:ok, %{access_token: access_token, refresh_token: refresh_token}} <-
Users.authenticate(%{user: user, password: password}) do Users.authenticate(%{user: user, password: password}) do
{:ok, %{access_token: access_token, refresh_token: refresh_token, user: user}} {:ok, %{access_token: access_token, refresh_token: refresh_token, user: user}}
@ -233,11 +234,7 @@ defmodule MobilizonWeb.Resolvers.User do
def change_default_actor( def change_default_actor(
_parent, _parent,
%{preferred_username: username}, %{preferred_username: username},
%{ %{context: %{current_user: user}}
context: %{
current_user: user
}
}
) do ) do
with %Actor{id: actor_id} <- Actors.get_local_actor_by_name(username), with %Actor{id: actor_id} <- Actors.get_local_actor_by_name(username),
{:user_actor, true} <- {:user_actor, true} <-

View File

@ -6,7 +6,7 @@ defmodule MobilizonWeb.Router do
pipeline :graphql do pipeline :graphql do
# plug(:accepts, ["json"]) # plug(:accepts, ["json"])
plug(MobilizonWeb.AuthPipeline) plug(MobilizonWeb.Auth.Pipeline)
end end
pipeline :well_known do pipeline :well_known do
@ -14,12 +14,12 @@ defmodule MobilizonWeb.Router do
end end
pipeline :activity_pub_signature do pipeline :activity_pub_signature do
plug(MobilizonWeb.HTTPSignaturePlug) plug(MobilizonWeb.Plugs.HTTPSignatures)
plug(MobilizonWeb.Plugs.MappedSignatureToIdentity) plug(MobilizonWeb.Plugs.MappedSignatureToIdentity)
end end
pipeline :relay do pipeline :relay do
plug(MobilizonWeb.HTTPSignaturePlug) plug(MobilizonWeb.Plugs.HTTPSignatures)
plug(MobilizonWeb.Plugs.MappedSignatureToIdentity) plug(MobilizonWeb.Plugs.MappedSignatureToIdentity)
plug(:accepts, ["activity-json", "json"]) plug(:accepts, ["activity-json", "json"])
end end
@ -58,7 +58,7 @@ defmodule MobilizonWeb.Router do
) )
end end
forward("/graphiql", Absinthe.Plug.GraphiQL, schema: MobilizonWeb.Schema) ## FEDERATION
scope "/.well-known", MobilizonWeb do scope "/.well-known", MobilizonWeb do
pipe_through(:well_known) pipe_through(:well_known)
@ -69,28 +69,6 @@ defmodule MobilizonWeb.Router do
get("/nodeinfo/:version", NodeInfoController, :nodeinfo) get("/nodeinfo/:version", NodeInfoController, :nodeinfo)
end end
scope "/", MobilizonWeb do
pipe_through(:atom_and_ical)
get("/@:name/feed/:format", FeedController, :actor)
get("/events/:uuid/export/:format", FeedController, :event)
get("/events/going/:token/:format", FeedController, :going)
end
scope "/", MobilizonWeb do
pipe_through(:browser)
# Because the "/events/:uuid" route caches all these, we need to force them
get("/events/create", PageController, :index)
get("/events/list", PageController, :index)
get("/events/me", PageController, :index)
get("/events/explore", PageController, :index)
get("/events/:uuid/edit", PageController, :index)
# This is a hack to ease link generation into emails
get("/moderation/reports/:id", PageController, :index, as: "moderation_report")
end
scope "/", MobilizonWeb do scope "/", MobilizonWeb do
pipe_through(:activity_pub_and_html) pipe_through(:activity_pub_and_html)
pipe_through(:activity_pub_signature) pipe_through(:activity_pub_signature)
@ -121,6 +99,34 @@ defmodule MobilizonWeb.Router do
post("/inbox", ActivityPubController, :inbox) post("/inbox", ActivityPubController, :inbox)
end end
## FEED
scope "/", MobilizonWeb do
pipe_through(:atom_and_ical)
get("/@:name/feed/:format", FeedController, :actor)
get("/events/:uuid/export/:format", FeedController, :event)
get("/events/going/:token/:format", FeedController, :going)
end
## MOBILIZON
forward("/graphiql", Absinthe.Plug.GraphiQL, schema: MobilizonWeb.Schema)
scope "/", MobilizonWeb do
pipe_through(:browser)
# Because the "/events/:uuid" route caches all these, we need to force them
get("/events/create", PageController, :index)
get("/events/list", PageController, :index)
get("/events/me", PageController, :index)
get("/events/explore", PageController, :index)
get("/events/:uuid/edit", PageController, :index)
# This is a hack to ease link generation into emails
get("/moderation/reports/:id", PageController, :index, as: "moderation_report")
end
scope "/proxy/", MobilizonWeb do scope "/proxy/", MobilizonWeb do
pipe_through(:remote_media) pipe_through(:remote_media)

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/mime.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/mime.ex
defmodule MobilizonWeb.MIME do defmodule MobilizonWeb.Upload.MIME do
@moduledoc """ @moduledoc """
Returns the mime-type of a binary and optionally a normalized file-name. Returns the mime-type of a binary and optionally a normalized file-name.
""" """

View File

@ -27,7 +27,7 @@ defmodule MobilizonWeb.Upload do
Related behaviors: Related behaviors:
* `MobilizonWeb.Uploaders.Uploader` * `MobilizonWeb.Upload.Uploader`
* `MobilizonWeb.Upload.Filter` * `MobilizonWeb.Upload.Filter`
""" """
@ -36,7 +36,7 @@ defmodule MobilizonWeb.Upload do
alias Mobilizon.Config alias Mobilizon.Config
alias MobilizonWeb.{MIME, Upload, Uploaders} alias MobilizonWeb.Upload.{Filter, MIME, Uploader}
require Logger require Logger
@ -69,8 +69,8 @@ defmodule MobilizonWeb.Upload do
with {:ok, upload} <- prepare_upload(upload, opts), with {:ok, upload} <- prepare_upload(upload, opts),
upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"}, upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"},
{:ok, upload} <- Upload.Filter.filter(opts.filters, upload), {:ok, upload} <- Filter.filter(opts.filters, upload),
{:ok, url_spec} <- Uploaders.Uploader.put_file(opts.uploader, upload) do {:ok, url_spec} <- Uploader.put_file(opts.uploader, upload) do
{:ok, {:ok,
%{ %{
name: Map.get(opts, :description) || upload.name, name: Map.get(opts, :description) || upload.name,
@ -92,7 +92,7 @@ defmodule MobilizonWeb.Upload do
with opts <- get_opts(opts), with opts <- get_opts(opts),
%URI{path: "/media/" <> path, host: host} <- URI.parse(url), %URI{path: "/media/" <> path, host: host} <- URI.parse(url),
{:same_host, true} <- {:same_host, host == MobilizonWeb.Endpoint.host()} do {:same_host, true} <- {:same_host, host == MobilizonWeb.Endpoint.host()} do
Uploaders.Uploader.remove_file(opts.uploader, path) Uploader.remove_file(opts.uploader, path)
else else
%URI{} = _uri -> %URI{} = _uri ->
{:error, "URL doesn't match pattern"} {:error, "URL doesn't match pattern"}

View File

@ -3,12 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/uploaders/local.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/uploaders/local.ex
defmodule MobilizonWeb.Uploaders.Local do defmodule MobilizonWeb.Upload.Uploader.Local do
@moduledoc """ @moduledoc """
Local uploader for files Local uploader for files
""" """
@behaviour MobilizonWeb.Uploaders.Uploader @behaviour MobilizonWeb.Upload.Uploader
alias Mobilizon.Config alias Mobilizon.Config

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/uploaders/uploader.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/uploaders/uploader.ex
defmodule MobilizonWeb.Uploaders.Uploader do defmodule MobilizonWeb.Upload.Uploader do
@moduledoc """ @moduledoc """
Defines the contract to put and get an uploaded file to any backend. Defines the contract to put and get an uploaded file to any backend.
""" """

View File

@ -3,8 +3,10 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Activity, Utils, Convertible} alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.{Activity, Utils}
alias Mobilizon.Federation.ActivityStream.Convertible
@private_visibility_empty_collection %{elements: [], total: 0} @private_visibility_empty_collection %{elements: [], total: 0}

View File

@ -1,7 +1,7 @@
defmodule MobilizonWeb.ActivityPub.ObjectView do defmodule MobilizonWeb.ActivityPub.ObjectView do
use MobilizonWeb, :view use MobilizonWeb, :view
alias Mobilizon.Service.ActivityPub.{Activity, Utils} alias Mobilizon.Federation.ActivityPub.{Activity, Utils}
def render("activity.json", %{activity: %Activity{local: local, data: data} = activity}) do def render("activity.json", %{activity: %Activity{local: local, data: data} = activity}) do
%{ %{

View File

@ -2,14 +2,19 @@ defmodule MobilizonWeb.PageView do
@moduledoc """ @moduledoc """
View for our webapp View for our webapp
""" """
use MobilizonWeb, :view use MobilizonWeb, :view
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Tombstone
alias Mobilizon.Service.ActivityPub.{Convertible, Utils}
alias Mobilizon.Service.Metadata
alias Mobilizon.Service.MetadataUtils
alias Mobilizon.Service.Metadata.Instance
alias Mobilizon.Events.{Comment, Event} alias Mobilizon.Events.{Comment, Event}
alias Mobilizon.Tombstone
alias Mobilizon.Service.Metadata
alias Mobilizon.Service.Metadata.Instance
alias Mobilizon.Service.Metadata.Utils, as: MetadataUtils
alias Mobilizon.Federation.ActivityPub.Utils
alias Mobilizon.Federation.ActivityStream.Convertible
def render("actor.activity-json", %{conn: %{assigns: %{object: %Actor{} = actor}}}) do def render("actor.activity-json", %{conn: %{assigns: %{object: %Actor{} = actor}}}) do
actor actor

View File

@ -1,40 +0,0 @@
defmodule Mobilizon.Service.Admin.ActionLogService do
@moduledoc """
Module to handle action log creations.
"""
alias Mobilizon.Actors.Actor
alias Mobilizon.Admin
alias Mobilizon.Admin.ActionLog
alias Mobilizon.Users
alias Mobilizon.Users.User
@doc """
Log an admin action
"""
@spec log_action(Actor.t(), String.t(), String.t()) :: {:ok, ActionLog.t()}
def log_action(%Actor{user_id: user_id, id: actor_id}, action, target) do
with %User{role: role} <- Users.get_user!(user_id),
{:role, true} <- {:role, role in [:administrator, :moderator]},
{:ok, %ActionLog{} = create_action_log} <-
Admin.create_action_log(%{
"actor_id" => actor_id,
"target_type" => to_string(target.__struct__),
"target_id" => target.id,
"action" => action,
"changes" => stringify_struct(target)
}) do
{:ok, create_action_log}
end
end
defp stringify_struct(%_{} = struct) do
association_fields = struct.__struct__.__schema__(:associations)
struct
|> Map.from_struct()
|> Map.drop(association_fields ++ [:__meta__])
end
defp stringify_struct(struct), do: struct
end

View File

@ -1,50 +0,0 @@
defmodule Mobilizon.Service.Events.Tool do
@moduledoc """
Event-related tools
"""
alias Mobilizon.Events
alias Mobilizon.Events.Event
alias Mobilizon.Actors.Actor
alias Mobilizon.Users.User
alias MobilizonWeb.Email
alias Mobilizon.Storage.Repo
@important_changes [:title, :begins_on, :ends_on, :status]
def calculate_event_diff_and_send_notifications(
%Event{} = old_event,
%Event{id: event_id} = event,
changes
) do
important = MapSet.new(@important_changes)
diff =
changes
|> Map.keys()
|> MapSet.new()
|> MapSet.intersection(important)
if MapSet.size(diff) > 0 do
Repo.transaction(fn ->
event_id
|> Events.list_local_emails_user_participants_for_event_query()
|> Repo.stream()
|> Enum.to_list()
|> Enum.each(
&send_notification_for_event_update_to_participant(&1, old_event, event, diff)
)
end)
end
end
defp send_notification_for_event_update_to_participant(
{%Actor{} = actor, %User{locale: locale} = user},
%Event{} = old_event,
%Event{} = event,
diff
) do
user
|> Email.Event.event_updated(actor, old_event, event, diff, locale)
|> Email.Mailer.deliver_later()
end
end

View File

@ -3,21 +3,15 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/html.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/html.ex
defmodule Mobilizon.Service.HTML do defmodule Mobilizon.Service.Formatter.DefaultScrubbler do
@moduledoc """ @moduledoc """
Service to filter tags out of HTML content Custom strategy to filter HTML content.
""" """
alias HtmlSanitizeEx.Scrubber
alias Mobilizon.Service.HTML.Scrubber.Default
def filter_tags(html), do: Scrubber.scrub(html, Default) alias HtmlSanitizeEx.Scrubber.Meta
end
defmodule Mobilizon.Service.HTML.Scrubber.Default do
@moduledoc "Custom strategy to filter HTML content"
require HtmlSanitizeEx.Scrubber.Meta require HtmlSanitizeEx.Scrubber.Meta
alias HtmlSanitizeEx.Scrubber.Meta
# credo:disable-for-previous-line # credo:disable-for-previous-line
# No idea how to fix this one… # No idea how to fix this one…

View File

@ -10,18 +10,18 @@ defmodule Mobilizon.Service.Formatter do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Service.HTML alias Mobilizon.Service.Formatter.HTML
@link_regex ~r"((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+"ui @link_regex ~r"((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~%:/?#[\]@!\$&'\(\)\*\+,;=.]+)|[0-9a-z+\-\.]+:[0-9a-z$-_.+!*'(),]+"ui
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/ @markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
@auto_linker_config hashtag: true, @auto_linker_config hashtag: true,
hashtag_handler: &Mobilizon.Service.Formatter.hashtag_handler/4, hashtag_handler: &__MODULE__.hashtag_handler/4,
mention: true, mention: true,
mention_handler: &Mobilizon.Service.Formatter.mention_handler/4 mention_handler: &__MODULE__.mention_handler/4
def escape_mention_handler("@" <> nickname = mention, buffer, _, _) do def escape_mention_handler("@" <> nickname = mention, buffer, _, _) do
case Mobilizon.Actors.get_actor_by_name(nickname) do case Actors.get_actor_by_name(nickname) do
%Actor{} -> %Actor{} ->
# escape markdown characters with `\\` # escape markdown characters with `\\`
# (we don't want something like @user__name to be parsed by markdown) # (we don't want something like @user__name to be parsed by markdown)

View File

@ -0,0 +1,16 @@
# Portions of this file are derived from Pleroma:
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/html.ex
defmodule Mobilizon.Service.Formatter.HTML do
@moduledoc """
Service to filter tags out of HTML content.
"""
alias HtmlSanitizeEx.Scrubber
alias Mobilizon.Service.Formatter.DefaultScrubbler
def filter_tags(html), do: Scrubber.scrub(html, DefaultScrubbler)
end

View File

@ -1,20 +0,0 @@
defprotocol Mobilizon.Service.Metadata do
@doc """
Build tags
"""
def build_tags(entity)
end
defmodule Mobilizon.Service.MetadataUtils do
@moduledoc """
Tools to convert tags to string
"""
alias Phoenix.HTML
def stringify_tags(tags) do
Enum.reduce(tags, "", &stringify_tag/2)
end
defp stringify_tag(tag, acc) when is_tuple(tag), do: acc <> HTML.safe_to_string(tag)
defp stringify_tag(tag, acc) when is_binary(tag), do: acc <> tag
end

View File

@ -0,0 +1,7 @@
defprotocol Mobilizon.Service.Metadata do
@doc """
Build tags
"""
def build_tags(entity)
end

View File

@ -0,0 +1,12 @@
defmodule Mobilizon.Service.Metadata.Utils do
@moduledoc """
Tools to convert tags to string.
"""
alias Phoenix.HTML
def stringify_tags(tags), do: Enum.reduce(tags, "", &stringify_tag/2)
defp stringify_tag(tag, acc) when is_tuple(tag), do: acc <> HTML.safe_to_string(tag)
defp stringify_tag(tag, acc) when is_binary(tag), do: acc <> tag
end

View File

@ -2,8 +2,8 @@ defmodule Mobilizon.Service.Statistics do
@moduledoc """ @moduledoc """
A module that provides cached statistics A module that provides cached statistics
""" """
alias Mobilizon.Events
alias Mobilizon.Users alias Mobilizon.{Events, Users}
def get_cached_value(key) do def get_cached_value(key) do
case Cachex.fetch(:statistics, key, fn key -> case Cachex.fetch(:statistics, key, fn key ->

View File

@ -1,46 +0,0 @@
defmodule Mobilizon.Service.Users.Activation do
@moduledoc false
alias Mobilizon.Service.Users.Tools
alias Mobilizon.Users
alias Mobilizon.Users.User
alias MobilizonWeb.Email
require Logger
@doc false
def check_confirmation_token(token) when is_binary(token) do
with %User{} = user <- Users.get_user_by_activation_token(token),
{:ok, %User{} = user} <-
Users.update_user(user, %{
"confirmed_at" => DateTime.utc_now() |> DateTime.truncate(:second),
"confirmation_sent_at" => nil,
"confirmation_token" => nil
}) do
Logger.info("User #{user.email} has been confirmed")
{:ok, user}
else
_err ->
{:error, :invalid_token}
end
end
def resend_confirmation_email(%User{} = user, locale \\ "en") do
with :ok <- Tools.we_can_send_email(user, :confirmation_sent_at),
{:ok, user} <-
Users.update_user(user, %{
"confirmation_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
}) do
send_confirmation_email(user, locale)
Logger.info("Sent confirmation email again to #{user.email}")
{:ok, user.email}
end
end
def send_confirmation_email(%User{} = user, locale \\ "en") do
user
|> Email.User.confirmation_email(locale)
|> Email.Mailer.deliver_later()
end
end

View File

@ -1,62 +0,0 @@
defmodule Mobilizon.Service.Users.ResetPassword do
@moduledoc false
alias Mobilizon.Service.Users.Tools
alias Mobilizon.Storage.Repo
alias Mobilizon.Users
alias Mobilizon.Users.User
alias MobilizonWeb.Email
require Logger
@doc """
Check that the provided token is correct and update provided password
"""
@spec check_reset_password_token(String.t(), String.t()) :: tuple
def check_reset_password_token(password, token) do
with %User{} = user <- Users.get_user_by_reset_password_token(token),
{:ok, %User{} = user} <-
Repo.update(
User.password_reset_changeset(user, %{
"password" => password,
"reset_password_sent_at" => nil,
"reset_password_token" => nil
})
) do
{:ok, user}
else
{:error, %Ecto.Changeset{errors: [password: {"registration.error.password_too_short", _}]}} ->
{:error,
"The password you have choosen is too short. Please make sure your password contains at least 6 charaters."}
_err ->
{:error,
"The token you provided is invalid. Make sure that the URL is exactly the one provided inside the email you got."}
end
end
@doc """
Send the email reset password, if it's not too soon since the last send
"""
@spec send_password_reset_email(User.t(), String.t()) :: tuple
def send_password_reset_email(%User{} = user, locale \\ "en") do
with :ok <- Tools.we_can_send_email(user, :reset_password_sent_at),
{:ok, %User{} = user_updated} <-
Repo.update(
User.send_password_reset_changeset(user, %{
"reset_password_token" => Tools.random_string(30),
"reset_password_sent_at" => DateTime.utc_now() |> DateTime.truncate(:second)
})
) do
mail =
user_updated
|> Email.User.reset_password_email(locale)
|> Email.Mailer.deliver_later()
{:ok, mail}
else
{:error, reason} -> {:error, reason}
end
end
end

View File

@ -1,43 +0,0 @@
defmodule Mobilizon.Service.Users.Tools do
@moduledoc """
Common functions for actors services
"""
alias Mobilizon.Users.User
@spec we_can_send_email(User.t(), atom()) :: :ok | {:error, :email_too_soon}
def we_can_send_email(%User{} = user, key \\ :reset_password_sent_at) do
case Map.get(user, key) do
nil ->
:ok
_ ->
case Timex.before?(
Timex.shift(Map.get(user, key), hours: 1),
DateTime.utc_now() |> DateTime.truncate(:second)
) do
true ->
:ok
false ->
{:error, :email_too_soon}
end
end
end
@spec random_string(integer) :: String.t()
def random_string(length) do
length
|> :crypto.strong_rand_bytes()
|> Base.url_encode64()
end
end
defmodule Mobilizon.Users.Guards do
@moduledoc """
Guards for users
"""
defguard is_admin(role) when is_atom(role) and role == :administrator
defguard is_moderator(role) when is_atom(role) and role in [:administrator, :moderator]
end

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.Workers.BackgroundWorker do defmodule Mobilizon.Service.Workers.Background do
@moduledoc """ @moduledoc """
Worker to build search results Worker to build search results
""" """
@ -6,7 +6,7 @@ defmodule Mobilizon.Service.Workers.BackgroundWorker do
alias Mobilizon.Actors alias Mobilizon.Actors
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
use Mobilizon.Service.Workers.WorkerHelper, queue: "background" use Mobilizon.Service.Workers.Helper, queue: "background"
@impl Oban.Worker @impl Oban.Worker
def perform(%{"op" => "delete_actor", "actor_id" => actor_id}, _job) do def perform(%{"op" => "delete_actor", "actor_id" => actor_id}, _job) do

View File

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.Workers.BuildSearchWorker do defmodule Mobilizon.Service.Workers.BuildSearch do
@moduledoc """ @moduledoc """
Worker to build search results Worker to build search results
""" """
@ -8,7 +8,7 @@ defmodule Mobilizon.Service.Workers.BuildSearchWorker do
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
alias Ecto.Adapters.SQL alias Ecto.Adapters.SQL
use Mobilizon.Service.Workers.WorkerHelper, queue: "search" use Mobilizon.Service.Workers.Helper, queue: "search"
@impl Oban.Worker @impl Oban.Worker
def perform(%{"op" => "insert_search_event", "event_id" => event_id}, _job) do def perform(%{"op" => "insert_search_event", "event_id" => event_id}, _job) do

View File

@ -3,12 +3,14 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/workers/worker_helper.ex # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/workers/worker_helper.ex
defmodule Mobilizon.Service.Workers.WorkerHelper do defmodule Mobilizon.Service.Workers.Helper do
@moduledoc """ @moduledoc """
Tools to ease dealing with workers Tools to ease dealing with workers
""" """
alias Mobilizon.Config alias Mobilizon.Config
alias Mobilizon.Service.Workers.WorkerHelper alias Mobilizon.Service.Workers.Helper
alias Mobilizon.Storage.Repo
def worker_args(queue) do def worker_args(queue) do
case Config.get([:workers, :retries, queue]) do case Config.get([:workers, :retries, queue]) do
@ -39,11 +41,11 @@ defmodule Mobilizon.Service.Workers.WorkerHelper do
def enqueue(operation, params, worker_args \\ []) do def enqueue(operation, params, worker_args \\ []) do
params = Map.merge(%{"op" => operation}, params) params = Map.merge(%{"op" => operation}, params)
queue_atom = String.to_existing_atom(unquote(queue)) queue_atom = String.to_existing_atom(unquote(queue))
worker_args = worker_args ++ WorkerHelper.worker_args(queue_atom) worker_args = worker_args ++ Helper.worker_args(queue_atom)
unquote(caller_module) unquote(caller_module)
|> apply(:new, [params, worker_args]) |> apply(:new, [params, worker_args])
|> Mobilizon.Storage.Repo.insert() |> Repo.insert()
end end
end end
end end

157
mix.exs
View File

@ -181,8 +181,9 @@ defmodule Mobilizon.Mixfile do
Mobilizon.Actors.Member, Mobilizon.Actors.Member,
Mobilizon.Addresses, Mobilizon.Addresses,
Mobilizon.Addresses.Address, Mobilizon.Addresses.Address,
Mobilizon.Admin,
Mobilizon.Admin.ActionLog,
Mobilizon.Events, Mobilizon.Events,
Mobilizon.Service.ActivityPub.Activity,
Mobilizon.Events.Event, Mobilizon.Events.Event,
Mobilizon.Events.Comment, Mobilizon.Events.Comment,
Mobilizon.Events.FeedToken, Mobilizon.Events.FeedToken,
@ -191,7 +192,7 @@ defmodule Mobilizon.Mixfile do
Mobilizon.Events.Tag, Mobilizon.Events.Tag,
Mobilizon.Events.TagRelations, Mobilizon.Events.TagRelations,
Mobilizon.Events.Track, Mobilizon.Events.Track,
Mobilizon.Event.EventCategory, Mobilizon.Events.EventCategory,
Mobilizon.Events.CommentVisibility, Mobilizon.Events.CommentVisibility,
Mobilizon.Events.EventStatus, Mobilizon.Events.EventStatus,
Mobilizon.Events.EventVisibility, Mobilizon.Events.EventVisibility,
@ -200,110 +201,184 @@ defmodule Mobilizon.Mixfile do
Mobilizon.Events.Tag.TitleSlug, Mobilizon.Events.Tag.TitleSlug,
Mobilizon.Events.Tag.TitleSlug.Type, Mobilizon.Events.Tag.TitleSlug.Type,
Mobilizon.Events.TagRelation, Mobilizon.Events.TagRelation,
Mobilizon.Media,
Mobilizon.Media.File,
Mobilizon.Media.Picture,
Mobilizon.Mention,
Mobilizon.Reports,
Mobilizon.Reports.Note,
Mobilizon.Reports.Report,
Mobilizon.Share,
Mobilizon.Tombstone,
Mobilizon.Users, Mobilizon.Users,
Mobilizon.Users.User, Mobilizon.Users.User,
Mobilizon.Users.UserRole, Mobilizon.Users.UserRole,
Mobilizon.Users.Guards, Mobilizon.Federation.ActivityPub.Activity
Mobilizon.Storage.Ecto,
Mobilizon.Storage.Repo
], ],
APIs: [ APIs: [
MobilizonWeb.API.Comments, MobilizonWeb.API.Comments,
MobilizonWeb.API.Events, MobilizonWeb.API.Events,
MobilizonWeb.API.Follows,
MobilizonWeb.API.Groups, MobilizonWeb.API.Groups,
MobilizonWeb.API.Participations,
MobilizonWeb.API.Reports,
MobilizonWeb.API.Search, MobilizonWeb.API.Search,
MobilizonWeb.API.Utils MobilizonWeb.API.Utils
], ],
Web: [ Web: [
MobilizonWeb, MobilizonWeb,
MobilizonWeb.PageView, MobilizonWeb.Endpoint,
MobilizonWeb.Router, MobilizonWeb.Router,
MobilizonWeb.Router.Helpers, MobilizonWeb.Router.Helpers,
MobilizonWeb.AuthErrorHandler, MobilizonWeb.Plugs.UploadedMedia,
MobilizonWeb.AuthPipeline,
MobilizonWeb.Cache,
MobilizonWeb.ChangesetView,
MobilizonWeb.Context,
MobilizonWeb.Endpoint,
MobilizonWeb.ErrorHelpers,
MobilizonWeb.ErrorView,
MobilizonWeb.FallbackController, MobilizonWeb.FallbackController,
MobilizonWeb.FeedController, MobilizonWeb.FeedController,
MobilizonWeb.Gettext, MobilizonWeb.MediaProxyController,
MobilizonWeb.Guardian,
MobilizonWeb.Guardian.Plug,
MobilizonWeb.JsonLD.ObjectView,
MobilizonWeb.PageController, MobilizonWeb.PageController,
MobilizonWeb.Uploaders.Avatar, MobilizonWeb.ChangesetView,
MobilizonWeb.Uploaders.Category, MobilizonWeb.JsonLD.ObjectView,
MobilizonWeb.Uploaders.Category.Type MobilizonWeb.EmailView,
MobilizonWeb.ErrorHelpers,
MobilizonWeb.ErrorView,
MobilizonWeb.LayoutView,
MobilizonWeb.PageView,
MobilizonWeb.Auth.Context,
MobilizonWeb.Auth.ErrorHandler,
MobilizonWeb.Auth.Guardian,
MobilizonWeb.Auth.Pipeline,
MobilizonWeb.Cache,
MobilizonWeb.Cache.ActivityPub,
MobilizonWeb.Email,
MobilizonWeb.Email.Admin,
MobilizonWeb.Email.Checker,
MobilizonWeb.Email.Event,
MobilizonWeb.Email.Mailer,
MobilizonWeb.Email.Participation,
MobilizonWeb.Email.User,
MobilizonWeb.Upload,
MobilizonWeb.Upload.Filter,
MobilizonWeb.Upload.Filter.AnonymizeFilename,
MobilizonWeb.Upload.Filter.Dedupe,
MobilizonWeb.Upload.Filter.Mogrify,
MobilizonWeb.Upload.Filter.Optimize,
MobilizonWeb.Upload.MIME,
MobilizonWeb.Upload.Uploader,
MobilizonWeb.Upload.Uploader.Local,
MobilizonWeb.MediaProxy,
MobilizonWeb.ReverseProxy
], ],
Geospatial: [ Geospatial: [
Mobilizon.Service.Geospatial, Mobilizon.Service.Geospatial,
Mobilizon.Service.Geospatial.Addok, Mobilizon.Service.Geospatial.Addok,
Mobilizon.Service.Geospatial.GoogleMaps, Mobilizon.Service.Geospatial.GoogleMaps,
Mobilizon.Service.Geospatial.MapQuest, Mobilizon.Service.Geospatial.MapQuest,
Mobilizon.Service.Geospatial.Mimirsbrunn,
Mobilizon.Service.Geospatial.Nominatim, Mobilizon.Service.Geospatial.Nominatim,
Mobilizon.Service.Geospatial.Pelias,
Mobilizon.Service.Geospatial.Photon, Mobilizon.Service.Geospatial.Photon,
Mobilizon.Service.Geospatial.Provider Mobilizon.Service.Geospatial.Provider
], ],
Localization: [
Mobilizon.Cldr,
MobilizonWeb.Gettext
],
GraphQL: [ GraphQL: [
MobilizonWeb.GraphQLSocket,
MobilizonWeb.Resolvers.Address, MobilizonWeb.Resolvers.Address,
MobilizonWeb.Resolvers.Admin,
MobilizonWeb.Resolvers.Comment, MobilizonWeb.Resolvers.Comment,
MobilizonWeb.Resolvers.Config,
MobilizonWeb.Resolvers.Event, MobilizonWeb.Resolvers.Event,
MobilizonWeb.Resolvers.FeedToken, MobilizonWeb.Resolvers.FeedToken,
MobilizonWeb.Resolvers.Group, MobilizonWeb.Resolvers.Group,
MobilizonWeb.Resolvers.Member,
MobilizonWeb.Resolvers.Person, MobilizonWeb.Resolvers.Person,
MobilizonWeb.Resolvers.Picture,
MobilizonWeb.Resolvers.Report,
MobilizonWeb.Resolvers.Search, MobilizonWeb.Resolvers.Search,
MobilizonWeb.Resolvers.Tag, MobilizonWeb.Resolvers.Tag,
MobilizonWeb.Resolvers.User, MobilizonWeb.Resolvers.User,
MobilizonWeb.Schema, MobilizonWeb.Schema,
MobilizonWeb.Schema.ActorInterface, MobilizonWeb.Schema.ActorInterface,
MobilizonWeb.Schema.Actors.ApplicationType,
MobilizonWeb.Schema.Actors.FollowerType, MobilizonWeb.Schema.Actors.FollowerType,
MobilizonWeb.Schema.Actors.GroupType, MobilizonWeb.Schema.Actors.GroupType,
MobilizonWeb.Schema.Actors.MemberType, MobilizonWeb.Schema.Actors.MemberType,
MobilizonWeb.Schema.Actors.PersonType, MobilizonWeb.Schema.Actors.PersonType,
MobilizonWeb.Schema.AddressType, MobilizonWeb.Schema.AddressType,
MobilizonWeb.Schema.AdminType,
MobilizonWeb.Schema.CommentType, MobilizonWeb.Schema.CommentType,
MobilizonWeb.Schema.Custom.Point, MobilizonWeb.Schema.ConfigType,
MobilizonWeb.Schema.Custom.UUID,
MobilizonWeb.Schema.EventType, MobilizonWeb.Schema.EventType,
MobilizonWeb.Schema.Events.FeedTokenType, MobilizonWeb.Schema.Events.FeedTokenType,
MobilizonWeb.Schema.Events.ParticipantType, MobilizonWeb.Schema.Events.ParticipantType,
MobilizonWeb.Schema.PictureType,
MobilizonWeb.Schema.ReportType,
MobilizonWeb.Schema.SearchType,
MobilizonWeb.Schema.SortType, MobilizonWeb.Schema.SortType,
MobilizonWeb.Schema.TagType, MobilizonWeb.Schema.TagType,
MobilizonWeb.Schema.UserType, MobilizonWeb.Schema.UserType,
MobilizonWeb.Schema.Utils MobilizonWeb.Schema.Utils,
MobilizonWeb.Schema.Custom.Point,
MobilizonWeb.Schema.Custom.UUID
], ],
ActivityPub: [ ActivityPub: [
MobilizonWeb.ActivityPub.ActorView, Mobilizon.Federation.ActivityPub,
MobilizonWeb.ActivityPub.ObjectView, Mobilizon.Federation.ActivityPub.Audience,
Mobilizon.Federation.ActivityPub.Federator,
Mobilizon.Federation.ActivityPub.Relay,
Mobilizon.Federation.ActivityPub.Transmogrifier,
Mobilizon.Federation.ActivityPub.Visibility,
Mobilizon.Federation.ActivityPub.Utils,
Mobilizon.Federation.ActivityStream.Convertible,
Mobilizon.Federation.ActivityStream.Converter,
Mobilizon.Federation.ActivityStream.Converter.Actor,
Mobilizon.Federation.ActivityStream.Converter.Address,
Mobilizon.Federation.ActivityStream.Converter.Comment,
Mobilizon.Federation.ActivityStream.Converter.Event,
Mobilizon.Federation.ActivityStream.Converter.Flag,
Mobilizon.Federation.ActivityStream.Converter.Follower,
Mobilizon.Federation.ActivityStream.Converter.Participant,
Mobilizon.Federation.ActivityStream.Converter.Picture,
Mobilizon.Federation.ActivityStream.Converter.Tombstone,
Mobilizon.Federation.ActivityStream.Converter.Utils,
Mobilizon.Federation.HTTPSignatures.Signature,
Mobilizon.Federation.WebFinger,
Mobilizon.Federation.WebFinger.XmlBuilder,
MobilizonWeb.Plugs.Federating,
MobilizonWeb.Plugs.HTTPSignatures,
MobilizonWeb.Plugs.MappedSignatureToIdentity,
MobilizonWeb.ActivityPubController, MobilizonWeb.ActivityPubController,
Mobilizon.Service.ActivityPub,
Mobilizon.Service.ActivityPub.Transmogrifier,
Mobilizon.Service.ActivityPub.Utils,
MobilizonWeb.HTTPSignaturePlug,
MobilizonWeb.WebFingerController,
MobilizonWeb.NodeInfoController, MobilizonWeb.NodeInfoController,
Mobilizon.Service.HTTPSignatures.Signature, MobilizonWeb.WebFingerController,
Mobilizon.Service.WebFinger, MobilizonWeb.ActivityPub.ActorView,
Mobilizon.Service.XmlBuilder, MobilizonWeb.ActivityPub.ObjectView
Mobilizon.Service.Federator
], ],
Services: [ Services: [
Mobilizon.Service.EmailChecker,
Mobilizon.Service.Export.Feed, Mobilizon.Service.Export.Feed,
Mobilizon.Service.Export.ICalendar, Mobilizon.Service.Export.ICalendar,
Mobilizon.Service.Metadata,
Mobilizon.Service.Formatter, Mobilizon.Service.Formatter,
Mobilizon.Service.Users.Tools Mobilizon.Service.Formatter.HTML,
Mobilizon.Service.Formatter.DefaultScrubbler,
Mobilizon.Service.Metadata,
Mobilizon.Service.Metadata.Actor,
Mobilizon.Service.Metadata.Comment,
Mobilizon.Service.Metadata.Event,
Mobilizon.Service.Metadata.Instance,
Mobilizon.Service.Metadata.Utils,
Mobilizon.Service.Statistics,
Mobilizon.Service.Workers.Background,
Mobilizon.Service.Workers.BuildSearch,
Mobilizon.Service.Workers.Helper
], ],
Tools: [ Tools: [
Mobilizon.Application, Mobilizon.Application,
Mobilizon.Config,
Mobilizon.Crypto,
Mobilizon.Factory, Mobilizon.Factory,
MobilizonWeb.Email.Mailer, Mobilizon.Storage.Ecto,
MobilizonWeb.Email.User, Mobilizon.Storage.Page,
MobilizonWeb.EmailView Mobilizon.Storage.Repo
] ]
] ]
end end

View File

@ -3,19 +3,18 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/web/activity_pub/activity_pub_test.exs # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/web/activity_pub/activity_pub_test.exs
defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do defmodule Mobilizon.Federation.ActivityPubTest do
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
use Mobilizon.DataCase use Mobilizon.DataCase
import Mock import Mock
import Mobilizon.Factory import Mobilizon.Factory
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.HTTPSignatures.Signature alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.HTTPSignatures.Signature
@activity_pub_public_audience "https://www.w3.org/ns/activitystreams#Public" @activity_pub_public_audience "https://www.w3.org/ns/activitystreams#Public"

View File

@ -2,10 +2,10 @@
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Mobilizon.Service.ActivityPub.RelayTest do defmodule Mobilizon.Federation.ActivityPub.RelayTest do
use Mobilizon.DataCase use Mobilizon.DataCase
alias Mobilizon.Service.ActivityPub.Relay alias Mobilizon.Federation.ActivityPub.Relay
test "gets an actor for the relay" do test "gets an actor for the relay" do
actor = Relay.get_actor() actor = Relay.get_actor()

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/web/activity_pub/transmogrifier_test.exs # Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/web/activity_pub/transmogrifier_test.exs
defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
use Mobilizon.DataCase use Mobilizon.DataCase
@ -14,9 +14,11 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
alias Mobilizon.{Actors, Events, Tombstone} alias Mobilizon.{Actors, Events, Tombstone}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events.{Comment, Event, Participant} alias Mobilizon.Events.{Comment, Event, Participant}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Activity, Utils, Convertible} alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Service.ActivityPub.Transmogrifier alias Mobilizon.Federation.ActivityPub.Utils
alias Mobilizon.Federation.ActivityPub.{Activity, Relay, Transmogrifier}
alias Mobilizon.Federation.ActivityStream.{Convertible}
alias MobilizonWeb.API alias MobilizonWeb.API
@ -788,7 +790,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
end end
test "it accepts Flag activities" do test "it accepts Flag activities" do
%Actor{url: reporter_url} = Mobilizon.Service.ActivityPub.Relay.get_actor() %Actor{url: reporter_url} = Relay.get_actor()
%Actor{url: reported_url} = reported = insert(:actor) %Actor{url: reported_url} = reported = insert(:actor)
%Comment{url: comment_url} = _comment = insert(:comment, actor: reported) %Comment{url: comment_url} = _comment = insert(:comment, actor: reported)

View File

@ -1,11 +1,11 @@
defmodule Mobilizon.Service.ActivityPub.UtilsTest do defmodule Mobilizon.Federation.ActivityPub.UtilsTest do
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
use Mobilizon.DataCase use Mobilizon.DataCase
import Mobilizon.Factory import Mobilizon.Factory
alias Mobilizon.Service.ActivityPub.Converter alias Mobilizon.Federation.ActivityStream.Converter
alias MobilizonWeb.Endpoint alias MobilizonWeb.Endpoint
alias MobilizonWeb.Router.Helpers, as: Routes alias MobilizonWeb.Router.Helpers, as: Routes

View File

@ -1,8 +1,9 @@
defmodule Mobilizon.Service.ActivityPub.Converter.ActorTest do defmodule Mobilizon.Federation.ActivityStream.Converter.ActorTest do
use Mobilizon.DataCase use Mobilizon.DataCase
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub.Converter.Actor, as: ActorConverter
alias Mobilizon.Federation.ActivityStream.Converter.Actor, as: ActorConverter
describe "actor to AS" do describe "actor to AS" do
test "valid actor to as" do test "valid actor to as" do

Some files were not shown because too many files have changed in this diff Show More