Fix software design suggestions

This commit is contained in:
miffigriffi 2019-09-22 18:29:13 +02:00 committed by Thomas Citharel
parent aed824f1aa
commit 0a0d07cf38
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
36 changed files with 292 additions and 208 deletions

View file

@ -5,13 +5,15 @@ defmodule Mix.Tasks.Mobilizon.Toot do
use Mix.Task
alias MobilizonWeb.API
require Logger
@shortdoc "Toot to an user"
def run([from, content]) do
Mix.Task.run("app.start")
case MobilizonWeb.API.Comments.create_comment(from, content) do
case API.Comments.create_comment(from, content) do
{:ok, _, _} ->
Mix.shell().info("Tooted")

View file

@ -23,7 +23,7 @@ defmodule Mobilizon do
@spec named_version :: String.t()
def named_version, do: "#{@name} #{@version}"
@spec user_agent :: String.t(:w)
@spec user_agent :: String.t()
def user_agent do
info = "#{MobilizonWeb.Endpoint.url()} <#{Config.get([:instance, :email], "")}>"

View file

@ -11,7 +11,7 @@ defmodule MobilizonWeb.API.Reports do
alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Reports, as: ReportsAction
alias Mobilizon.Reports.{Note, Report}
alias Mobilizon.Reports.{Note, Report, ReportStatus}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Users
@ -63,7 +63,7 @@ defmodule MobilizonWeb.API.Reports do
"""
def update_report_status(%Actor{} = actor, %Report{} = report, state) do
with {:valid_state, true} <-
{:valid_state, Mobilizon.Reports.ReportStatus.valid_value?(state)},
{:valid_state, ReportStatus.valid_value?(state)},
{:ok, report} <- ReportsAction.update_report(report, %{"status" => state}),
{:ok, _} <- log_action(actor, "update", report) do
{:ok, report}

View file

@ -6,6 +6,7 @@ defmodule MobilizonWeb.Cache.ActivityPub do
alias Mobilizon.{Actors, Events, Service}
alias Mobilizon.Actors.Actor
alias Mobilizon.Events.{Comment, Event}
alias Service.ActivityPub
@cache :activity_pub
@ -65,6 +66,6 @@ defmodule MobilizonWeb.Cache.ActivityPub do
"""
@spec get_relay :: {:commit, Actor.t()} | {:ignore, nil}
def get_relay do
Cachex.fetch(@cache, "relay_actor", &Service.ActivityPub.Relay.get_actor/0)
Cachex.fetch(@cache, "relay_actor", &ActivityPub.Relay.get_actor/0)
end
end

View file

@ -6,6 +6,8 @@
defmodule MobilizonWeb.MediaProxyController do
use MobilizonWeb, :controller
alias Plug.Conn
alias Mobilizon.Config
alias MobilizonWeb.MediaProxy
@ -21,10 +23,10 @@ defmodule MobilizonWeb.MediaProxyController do
ReverseProxy.call(conn, url, Keyword.get(config, :proxy_opts, @default_proxy_opts))
else
false ->
send_resp(conn, 404, Plug.Conn.Status.reason_phrase(404))
send_resp(conn, 404, Conn.Status.reason_phrase(404))
{:error, :invalid_signature} ->
send_resp(conn, 403, Plug.Conn.Status.reason_phrase(403))
send_resp(conn, 403, Conn.Status.reason_phrase(403))
{:wrong_filename, filename} ->
redirect(conn, external: MediaProxy.build_url(sig64, url64, filename))

View file

@ -9,6 +9,9 @@ defmodule MobilizonWeb.NodeInfoController do
alias Mobilizon.Config
alias Mobilizon.Service.Statistics
alias MobilizonWeb.Endpoint
alias MobilizonWeb.Router.Helpers, as: Routes
@node_info_supported_versions ["2.0", "2.1"]
@node_info_schema_uri "http://nodeinfo.diaspora.software/ns/schema/"
@ -18,8 +21,7 @@ defmodule MobilizonWeb.NodeInfoController do
|> Enum.map(fn version ->
%{
rel: @node_info_schema_uri <> version,
href:
MobilizonWeb.Router.Helpers.node_info_url(MobilizonWeb.Endpoint, :nodeinfo, version)
href: Routes.node_info_url(Endpoint, :nodeinfo, version)
}
end)

View file

@ -15,6 +15,7 @@ defmodule MobilizonWeb.Resolvers.Event do
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Users.User
alias MobilizonWeb.API
alias MobilizonWeb.Resolvers.Person
# We limit the max number of events that can be retrieved
@ -144,7 +145,7 @@ defmodule MobilizonWeb.Resolvers.Event do
{:has_event, {:ok, %Event{} = event}} <-
{:has_event, Mobilizon.Events.get_event_with_preload(event_id)},
{:error, :participant_not_found} <- Mobilizon.Events.get_participant(event_id, actor_id),
{:ok, _activity, participant} <- MobilizonWeb.API.Participations.join(event, actor),
{:ok, _activity, participant} <- API.Participations.join(event, actor),
participant <-
participant
|> Map.put(:event, event)
@ -180,7 +181,7 @@ defmodule MobilizonWeb.Resolvers.Event do
with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
{:has_event, {:ok, %Event{} = event}} <-
{:has_event, Mobilizon.Events.get_event_with_preload(event_id)},
{:ok, _activity, _participant} <- MobilizonWeb.API.Participations.leave(event, actor) do
{:ok, _activity, _participant} <- API.Participations.leave(event, actor) do
{:ok, %{event: %{id: event_id}, actor: %{id: actor_id}}}
else
{:has_event, _} ->

View file

@ -9,6 +9,7 @@ defmodule MobilizonWeb.Resolvers.Group do
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Users.User
alias MobilizonWeb.API
alias MobilizonWeb.Resolvers.Person
require Logger
@ -51,7 +52,7 @@ defmodule MobilizonWeb.Resolvers.Group do
%Activity{data: %{"object" => %{"type" => "Group"} = _object}},
%Actor{} = group
} <-
MobilizonWeb.API.Groups.create_group(
API.Groups.create_group(
user,
%{
preferred_username: args.preferred_username,

View file

@ -67,6 +67,8 @@ defmodule MobilizonWeb.ReverseProxy do
import Plug.Conn
alias Plug.Conn
require Logger
@type option ::
@ -131,7 +133,7 @@ defmodule MobilizonWeb.ReverseProxy do
|> error_or_redirect(
url,
code,
"Request failed: " <> Plug.Conn.Status.reason_phrase(code),
"Request failed: " <> Conn.Status.reason_phrase(code),
opts
)
|> halt()
@ -147,7 +149,7 @@ defmodule MobilizonWeb.ReverseProxy do
def call(conn, _, _) do
conn
|> send_resp(400, Plug.Conn.Status.reason_phrase(400))
|> send_resp(400, Conn.Status.reason_phrase(400))
|> halt()
end

View file

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

View file

@ -9,7 +9,7 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
@private_visibility_empty_collection %{elements: [], total: 0}
def render("actor.json", %{actor: actor}) do
public_key = Mobilizon.Service.ActivityPub.Utils.pem_to_public_key_pem(actor.keys)
public_key = Utils.pem_to_public_key_pem(actor.keys)
%{
"id" => actor.url,

View file

@ -4,12 +4,12 @@ defmodule MobilizonWeb.PageView do
"""
use MobilizonWeb, :view
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub.Utils
alias Mobilizon.Service.ActivityPub.{Converter, Utils}
alias Mobilizon.Service.Metadata
alias Mobilizon.Service.MetadataUtils
def render("actor.activity-json", %{conn: %{assigns: %{object: actor}}}) do
public_key = Mobilizon.Service.ActivityPub.Utils.pem_to_public_key_pem(actor.keys)
public_key = Utils.pem_to_public_key_pem(actor.keys)
%{
"id" => Actor.build_url(actor.preferred_username, :page),
@ -47,12 +47,12 @@ defmodule MobilizonWeb.PageView do
def render("event.activity-json", %{conn: %{assigns: %{object: event}}}) do
event
|> Mobilizon.Service.ActivityPub.Converters.Event.model_to_as()
|> Converter.Event.model_to_as()
|> Map.merge(Utils.make_json_ld_header())
end
def render("comment.activity-json", %{conn: %{assigns: %{object: comment}}}) do
comment = Mobilizon.Service.ActivityPub.Converters.Comment.model_to_as(comment)
comment = Converter.Comment.model_to_as(comment)
%{
"actor" => comment["actor"],

View file

@ -13,7 +13,7 @@ defmodule Mobilizon.Service.ActivityPub do
alias Mobilizon.{Actors, Config, Events}
alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Events.{Comment, Event, Participant}
alias Mobilizon.Service.ActivityPub.{Activity, Convertible, Transmogrifier}
alias Mobilizon.Service.ActivityPub.{Activity, Converter, Convertible, Relay, Transmogrifier}
alias Mobilizon.Service.{Federator, WebFinger}
alias Mobilizon.Service.HTTPSignatures.Signature
@ -535,7 +535,8 @@ defmodule Mobilizon.Service.ActivityPub do
if public && !is_delete_activity?(activity) && Config.get([:instance, :allow_relay]) do
Logger.info(fn -> "Relaying #{activity.data["id"]} out" end)
Mobilizon.Service.ActivityPub.Relay.publish(activity)
Relay.publish(activity)
end
followers =
@ -694,7 +695,7 @@ defmodule Mobilizon.Service.ActivityPub do
%Activity{
recipients: ["https://www.w3.org/ns/activitystreams#Public"],
actor: event.organizer_actor.url,
data: event |> Mobilizon.Service.ActivityPub.Converters.Event.model_to_as(),
data: Converter.Event.model_to_as(event),
local: local
}
end
@ -705,7 +706,7 @@ defmodule Mobilizon.Service.ActivityPub do
%Activity{
recipients: ["https://www.w3.org/ns/activitystreams#Public"],
actor: comment.actor.url,
data: comment |> Mobilizon.Service.ActivityPub.Converters.Comment.model_to_as(),
data: Converter.Comment.model_to_as(comment),
local: local
}
end

View file

@ -1,16 +1,11 @@
defmodule Mobilizon.Service.ActivityPub.Converter do
@moduledoc """
Converter behaviour
Converter behaviour.
This module allows to convert from ActivityStream format to our own internal one, and back
This module allows to convert from ActivityStream format to our own internal
one, and back.
"""
@callback as_to_model_data(map()) :: map()
@callback model_to_as(struct()) :: map()
end
defprotocol Mobilizon.Service.ActivityPub.Convertible do
@type activitystreams :: map()
@spec model_to_as(t) :: activitystreams
def model_to_as(convertible)
@callback as_to_model_data(map) :: map
@callback model_to_as(struct) :: map
end

View file

@ -1,21 +1,27 @@
defmodule Mobilizon.Service.ActivityPub.Converters.Actor do
defmodule Mobilizon.Service.ActivityPub.Converter.Actor do
@moduledoc """
Actor converter
Actor converter.
This module allows to convert events from ActivityStream format to our own
internal one, and back.
"""
alias Mobilizon.Actors.Actor, as: ActorModel
alias Mobilizon.Service.ActivityPub.Converter
alias Mobilizon.Service.ActivityPub.{Converter, Convertible}
@behaviour Converter
defimpl Convertible, for: ActorModel do
alias Mobilizon.Service.ActivityPub.Converter.Actor, as: ActorConverter
defdelegate model_to_as(actor), to: ActorConverter
end
@doc """
Converts an AP object data to our internal data structure
Converts an AP object data to our internal data structure.
"""
@impl Converter
@spec as_to_model_data(map()) :: map()
@spec as_to_model_data(map) :: map
def as_to_model_data(object) do
avatar =
object["icon"]["url"] &&
@ -45,10 +51,10 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Actor do
end
@doc """
Convert an actor struct to an ActivityStream representation
Convert an actor struct to an ActivityStream representation.
"""
@impl Converter
@spec model_to_as(ActorModel.t()) :: map()
@spec model_to_as(ActorModel.t()) :: map
def model_to_as(%ActorModel{} = actor) do
%{
"type" => Atom.to_string(actor.type),
@ -65,9 +71,3 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Actor do
}
end
end
defimpl Mobilizon.Service.ActivityPub.Convertible, for: Mobilizon.Actors.Actor do
alias Mobilizon.Service.ActivityPub.Converters.Actor, as: ActorConverter
defdelegate model_to_as(actor), to: ActorConverter
end

View file

@ -1,11 +1,9 @@
defmodule Mobilizon.Service.ActivityPub.Converters.Address do
defmodule Mobilizon.Service.ActivityPub.Converter.Address do
@moduledoc """
Address converter.
This module allows to convert reports from ActivityStream format to our own
internal one, and back.
Note: Reports are named Flag in AS.
"""
alias Mobilizon.Addresses.Address, as: AddressModel
@ -14,10 +12,10 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Address do
@behaviour Converter
@doc """
Converts an AP object data to our internal data structure
Converts an AP object data to our internal data structure.
"""
@impl Converter
@spec as_to_model_data(map()) :: map()
@spec as_to_model_data(map) :: map
def as_to_model_data(object) do
res = %{
"description" => object["name"],
@ -50,10 +48,10 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Address do
end
@doc """
Convert an event struct to an ActivityStream representation
Convert an event struct to an ActivityStream representation.
"""
@impl Converter
@spec model_to_as(AddressModel.t()) :: map()
@spec model_to_as(AddressModel.t()) :: map
def model_to_as(%AddressModel{} = address) do
res = %{
"type" => "Place",

View file

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converters.Comment do
defmodule Mobilizon.Service.ActivityPub.Converter.Comment do
@moduledoc """
Comment converter.
@ -10,19 +10,26 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Comment do
alias Mobilizon.Events.Comment, as: CommentModel
alias Mobilizon.Events.Event
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Converter
alias Mobilizon.Service.ActivityPub.{Converter, Convertible}
require Logger
@behaviour Converter
defimpl Convertible, for: CommentModel do
alias Mobilizon.Service.ActivityPub.Converter.Comment, as: CommentConverter
defdelegate model_to_as(comment), to: CommentConverter
end
@doc """
Converts an AP object data to our internal data structure
Converts an AP object data to our internal data structure.
"""
@impl Converter
@spec as_to_model_data(map()) :: map()
@spec as_to_model_data(map) :: map
def as_to_model_data(object) do
{:ok, %Actor{id: actor_id}} = ActivityPub.get_or_fetch_by_url(object["actor"])
Logger.debug("Inserting full comment")
Logger.debug(inspect(object))
@ -65,6 +72,7 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Comment do
end
else
Logger.debug("No parent object for this comment")
data
end
@ -75,7 +83,7 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Comment do
Make an AS comment object from an existing `Comment` structure.
"""
@impl Converter
@spec model_to_as(CommentModel.t()) :: map()
@spec model_to_as(CommentModel.t()) :: map
def model_to_as(%CommentModel{} = comment) do
object = %{
"type" => "Note",
@ -94,9 +102,3 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Comment do
end
end
end
defimpl Mobilizon.Service.ActivityPub.Convertible, for: Mobilizon.Events.Comment do
alias Mobilizon.Service.ActivityPub.Converters.Comment, as: CommentConverter
defdelegate model_to_as(comment), to: CommentConverter
end

View file

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converters.Event do
defmodule Mobilizon.Service.ActivityPub.Converter.Event do
@moduledoc """
Event converter.
@ -10,20 +10,27 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Event do
alias Mobilizon.Actors.Actor
alias Mobilizon.Addresses.Address
alias Mobilizon.Events.Event, as: EventModel
alias Mobilizon.Events.Tag
alias Mobilizon.Events.{EventOptions, Tag}
alias Mobilizon.Media.Picture
alias Mobilizon.Service.ActivityPub.{Converter, Utils}
alias Mobilizon.Service.ActivityPub.Converters.Address, as: AddressConverter
alias Mobilizon.Service.ActivityPub.{Converter, Convertible, Utils}
alias Mobilizon.Service.ActivityPub.Converter.Address, as: AddressConverter
alias Mobilizon.Service.ActivityPub.Converter.Picture, as: PictureConverter
require Logger
@behaviour Converter
defimpl Convertible, for: EventModel do
alias Mobilizon.Service.ActivityPub.Converter.Event, as: EventConverter
defdelegate model_to_as(event), to: EventConverter
end
@doc """
Converts an AP object data to our internal data structure
Converts an AP object data to our internal data structure.
"""
@impl Converter
@spec as_to_model_data(map()) :: map()
@spec as_to_model_data(map) :: map
def as_to_model_data(object) do
Logger.debug("event as_to_model_data")
Logger.debug(inspect(object))
@ -71,15 +78,57 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Event do
{:ok, Map.put(entity, "options", options)}
else
err ->
{:error, err}
error ->
{:error, error}
end
end
@doc """
Convert an event struct to an ActivityStream representation.
"""
@impl Converter
@spec model_to_as(EventModel.t()) :: map
def model_to_as(%EventModel{} = event) do
to =
if event.visibility == :public,
do: ["https://www.w3.org/ns/activitystreams#Public"],
else: [event.organizer_actor.followers_url]
res = %{
"type" => "Event",
"to" => to,
"cc" => [],
"attributedTo" => event.organizer_actor.url,
"name" => event.title,
"actor" => event.organizer_actor.url,
"uuid" => event.uuid,
"category" => event.category,
"content" => event.description,
"publish_at" => (event.publish_at || event.inserted_at) |> date_to_string(),
"updated_at" => event.updated_at |> date_to_string(),
"mediaType" => "text/html",
"startTime" => event.begins_on |> date_to_string(),
"endTime" => event.ends_on |> date_to_string(),
"tag" => event.tags |> build_tags(),
"id" => event.url,
"url" => event.url
}
res =
if is_nil(event.physical_address),
do: res,
else: Map.put(res, "location", AddressConverter.model_to_as(event.physical_address))
if is_nil(event.picture),
do: res,
else: Map.put(res, "attachment", [PictureConverter.model_to_as(event.picture)])
end
# Get only elements that we have in EventOptions
@spec get_options(map) :: map
defp get_options(object) do
keys =
Mobilizon.Events.EventOptions
EventOptions
|> struct
|> Map.keys()
|> List.delete(:__struct__)
@ -91,6 +140,7 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Event do
end)
end
@spec get_address(map | binary | nil) :: integer | nil
defp get_address(address_url) when is_bitstring(address_url) do
get_address(%{"id" => address_url})
end
@ -115,8 +165,9 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Event do
defp get_address(nil), do: nil
@spec do_get_address(map) :: integer | nil
defp do_get_address(map) do
map = Mobilizon.Service.ActivityPub.Converters.Address.as_to_model_data(map)
map = Mobilizon.Service.ActivityPub.Converter.Address.as_to_model_data(map)
case Addresses.create_address(map) do
{:ok, %Address{id: address_id}} ->
@ -127,6 +178,7 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Event do
end
end
@spec fetch_tags([String.t()]) :: [String.t()]
defp fetch_tags(tags) do
Logger.debug("fetching tags")
@ -141,6 +193,7 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Event do
end)
end
@spec build_tags([String.t()]) :: String.t()
defp build_tags(tags) do
Enum.map(tags, fn %Tag{} = tag ->
%{
@ -203,12 +256,7 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Event do
else: Map.put(res, "attachment", [Utils.make_picture_data(event.picture)])
end
@spec date_to_string(DateTime.t() | nil) :: String.t()
defp date_to_string(nil), do: nil
defp date_to_string(date), do: DateTime.to_iso8601(date)
end
defimpl Mobilizon.Service.ActivityPub.Convertible, for: Mobilizon.Events.Event do
alias Mobilizon.Service.ActivityPub.Converters.Event, as: EventConverter
defdelegate model_to_as(event), to: EventConverter
defp date_to_string(%DateTime{} = date), do: DateTime.to_iso8601(date)
end

View file

@ -1,4 +1,4 @@
defmodule Mobilizon.Service.ActivityPub.Converters.Flag do
defmodule Mobilizon.Service.ActivityPub.Converter.Flag do
@moduledoc """
Flag converter.
@ -18,10 +18,10 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Flag do
@behaviour Converter
@doc """
Converts an AP object data to our internal data structure
Converts an AP object data to our internal data structure.
"""
@impl Converter
@spec as_to_model_data(map()) :: map()
@spec as_to_model_data(map) :: map
def as_to_model_data(object) do
with params <- as_to_model(object) do
%{
@ -35,6 +35,21 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Flag do
end
end
@doc """
Convert an event struct to an ActivityStream representation
"""
@impl Converter
@spec model_to_as(EventModel.t()) :: map
def model_to_as(%Report{} = report) do
%{
"type" => "Flag",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"actor" => report.reporter.url,
"id" => report.url
}
end
@spec as_to_model(map) :: map
def as_to_model(%{"object" => objects} = object) do
with {:ok, %Actor{} = reporter} <- Actors.get_actor_by_url(object["actor"]),
%Actor{} = reported <-
@ -74,18 +89,4 @@ defmodule Mobilizon.Service.ActivityPub.Converters.Flag do
}
end
end
@doc """
Convert an event struct to an ActivityStream representation
"""
@impl Converter
@spec model_to_as(EventModel.t()) :: map()
def model_to_as(%Report{} = report) do
%{
"type" => "Flag",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"actor" => report.reporter.url,
"id" => report.url
}
end
end

View file

@ -0,0 +1,31 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Participant do
@moduledoc """
Participant converter.
This module allows to convert reports from ActivityStream format to our own
internal one, and back.
"""
alias Mobilizon.Events.Participant, as: ParticipantModel
alias Mobilizon.Service.ActivityPub.Convertible
defimpl Convertible, for: ParticipantModel do
alias Mobilizon.Service.ActivityPub.Converter.Participant, as: ParticipantConverter
defdelegate model_to_as(participant), to: ParticipantConverter
end
@doc """
Convert an event struct to an ActivityStream representation.
"""
@spec model_to_as(ParticipantModel.t()) :: map
def model_to_as(%ParticipantModel{} = participant) do
%{
"type" => "Join",
"id" => participant.url,
"actor" => participant.actor.url,
"object" => participant.event.url
}
end
end

View file

@ -0,0 +1,28 @@
defmodule Mobilizon.Service.ActivityPub.Converter.Picture do
@moduledoc """
Picture converter.
This module allows to convert events from ActivityStream format to our own
internal one, and back.
"""
alias Mobilizon.Media.Picture, as: PictureModel
@doc """
Convert a picture struct to an ActivityStream representation.
"""
@spec model_to_as(PictureModel.t()) :: map
def model_to_as(%PictureModel{file: file}) do
%{
"type" => "Document",
"url" => [
%{
"type" => "Link",
"mediaType" => file.content_type,
"href" => file.url
}
],
"name" => file.name
}
end
end

View file

@ -1,31 +0,0 @@
defmodule Mobilizon.Service.ActivityPub.Converters.Participant do
@moduledoc """
Participant converter.
This module allows to convert reports from ActivityStream format to our own
internal one, and back.
Note: Reports are named Flag in AS.
"""
alias Mobilizon.Events.Participant, as: ParticipantModel
@doc """
Convert an event struct to an ActivityStream representation
"""
@spec model_to_as(ParticipantModel.t()) :: map()
def model_to_as(%ParticipantModel{} = participant) do
%{
"type" => "Join",
"id" => participant.url,
"actor" => participant.actor.url,
"object" => participant.event.url
}
end
defimpl Mobilizon.Service.ActivityPub.Convertible, for: Mobilizon.Events.Participant do
alias Mobilizon.Service.ActivityPub.Converters.Participant, as: ParticipantConverter
defdelegate model_to_as(event), to: ParticipantConverter
end
end

View file

@ -0,0 +1,10 @@
defprotocol Mobilizon.Service.ActivityPub.Convertible do
@moduledoc """
Convertible protocol.
"""
@type activity_streams :: map
@spec model_to_as(t) :: activity_streams
def model_to_as(convertible)
end

View file

@ -11,7 +11,7 @@ defmodule Mobilizon.Service.ActivityPub.Relay do
alias Mobilizon.Actors
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Service.ActivityPub.{Activity, Transmogrifier}
alias MobilizonWeb.API.Follows
@ -72,9 +72,7 @@ defmodule Mobilizon.Service.ActivityPub.Relay do
def publish(%Activity{data: %{"object" => object}} = _activity) do
with %Actor{id: actor_id} = actor <- get_actor(),
{:ok, object} <-
Mobilizon.Service.ActivityPub.Transmogrifier.fetch_obj_helper_as_activity_streams(
object
) do
Transmogrifier.fetch_obj_helper_as_activity_streams(object) do
ActivityPub.announce(actor, object, "#{object["id"]}/announces/#{actor_id}", true, false)
else
e ->

View file

@ -13,7 +13,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
alias Mobilizon.Events
alias Mobilizon.Events.{Comment, Event, Participant}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.{Utils, Visibility}
alias Mobilizon.Service.ActivityPub.{Converter, Convertible, Utils, Visibility}
require Logger
@ -122,7 +122,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
def handle_incoming(%{"id" => ""}), do: :error
def handle_incoming(%{"type" => "Flag"} = data) do
with params <- Mobilizon.Service.ActivityPub.Converters.Flag.as_to_model(data) do
with params <- Converter.Flag.as_to_model(data) do
params = %{
reporter_url: params["reporter"].url,
reported_actor_url: params["reported"].url,
@ -868,7 +868,7 @@ defmodule Mobilizon.Service.ActivityPub.Transmogrifier do
def fetch_obj_helper_as_activity_streams(object) do
with {:ok, object} <- fetch_obj_helper(object) do
{:ok, Mobilizon.Service.ActivityPub.Convertible.model_to_as(object)}
{:ok, Convertible.model_to_as(object)}
end
end
end

View file

@ -16,7 +16,8 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
alias Mobilizon.Events.{Comment, Event}
alias Mobilizon.Media.Picture
alias Mobilizon.Reports.Report
alias Mobilizon.Service.ActivityPub.{Activity, Converters}
alias Mobilizon.Service.ActivityPub.{Activity, Converter}
alias Mobilizon.Service.Federator
alias Mobilizon.Storage.Repo
alias MobilizonWeb.{Email, Endpoint}
@ -64,7 +65,8 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
_ -> 5
end
Mobilizon.Service.Federator.enqueue(:publish, activity, priority)
Federator.enqueue(:publish, activity, priority)
:ok
end
@ -119,7 +121,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
def insert_full_object(%{"object" => %{"type" => "Event"} = object_data, "type" => "Create"})
when is_map(object_data) do
with {:ok, object_data} <-
Converters.Event.as_to_model_data(object_data),
Converter.Event.as_to_model_data(object_data),
{:ok, %Event{} = event} <- Events.create_event(object_data) do
{:ok, event}
end
@ -139,7 +141,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
"""
def insert_full_object(%{"object" => %{"type" => "Note"} = object_data, "type" => "Create"})
when is_map(object_data) do
with data <- Converters.Comment.as_to_model_data(object_data),
with data <- Converter.Comment.as_to_model_data(object_data),
{:ok, %Comment{} = comment} <- Events.create_comment(data) do
{:ok, comment}
else
@ -155,7 +157,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
"""
def insert_full_object(%{"type" => "Flag"} = object_data)
when is_map(object_data) do
with data <- Converters.Flag.as_to_model_data(object_data),
with data <- Converter.Flag.as_to_model_data(object_data),
{:ok, %Report{} = report} <- Reports.create_report(data) do
Enum.each(Users.list_moderators(), fn moderator ->
moderator
@ -187,7 +189,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
when is_map(object_data) do
with {:event_not_found, %Event{} = event} <-
{:event_not_found, Events.get_event_by_url(event_url)},
{:ok, object_data} <- Converters.Event.as_to_model_data(object_data),
{:ok, object_data} <- Converter.Event.as_to_model_data(object_data),
{:ok, %Event{} = event} <- Events.update_event(event, object_data) do
{:ok, event}
end
@ -199,7 +201,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
})
when is_map(object_data) and type_actor in @actor_types do
with {:ok, %Actor{} = actor} <- Actors.get_actor_by_url(actor_url),
object_data <- Converters.Actor.as_to_model_data(object_data),
object_data <- Converter.Actor.as_to_model_data(object_data),
{:ok, %Actor{} = actor} <- Actors.update_actor(actor, object_data) do
{:ok, actor}
end
@ -245,21 +247,10 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
end
@doc """
Convert a picture model into an AS Link representation
Convert a picture model into an AS Link representation.
"""
# TODO: Move me to Mobilizon.Service.ActivityPub.Converters
def make_picture_data(%Picture{file: file} = _picture) do
%{
"type" => "Document",
"url" => [
%{
"type" => "Link",
"mediaType" => file.content_type,
"href" => file.url
}
],
"name" => file.name
}
def make_picture_data(%Picture{} = picture) do
Converter.Picture.model_to_as(picture)
end
@doc """
@ -268,7 +259,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
def make_picture_data(picture) when is_map(picture) do
with {:ok, %{"url" => [%{"href" => url, "mediaType" => content_type}], "size" => size}} <-
MobilizonWeb.Upload.store(picture.file),
{:ok, %Picture{file: _file} = pic} <-
{:ok, %Picture{file: _file} = picture} <-
Mobilizon.Media.create_picture(%{
"file" => %{
"url" => url,
@ -278,7 +269,7 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
},
"actor_id" => picture.actor_id
}) do
make_picture_data(pic)
Converter.Picture.model_to_as(picture)
end
end

View file

@ -16,8 +16,11 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
alias Mobilizon.Events
alias Mobilizon.Events.Event
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Converter
alias Mobilizon.Service.HTTPSignatures.Signature
alias MobilizonWeb.ActivityPub.ActorView
setup_all do
HTTPoison.start()
end
@ -162,7 +165,7 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
test "it creates an update activity with the new actor data" do
actor = insert(:actor)
actor_data = MobilizonWeb.ActivityPub.ActorView.render("actor.json", %{actor: actor})
actor_data = ActorView.render("actor.json", %{actor: actor})
actor_data = Map.put(actor_data, "summary", @updated_actor_summary)
{:ok, update, updated_actor} =
@ -191,7 +194,7 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
test "it creates an update activity with the new event data" do
actor = insert(:actor)
event = insert(:event, organizer_actor: actor)
event_data = Mobilizon.Service.ActivityPub.Converters.Event.model_to_as(event)
event_data = Converter.Event.model_to_as(event)
event_data = Map.put(event_data, "startTime", @updated_start_time)
{:ok, update, updated_event} =

View file

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

View file

@ -18,6 +18,8 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
alias Mobilizon.Service.ActivityPub.{Activity, Utils}
alias Mobilizon.Service.ActivityPub.Transmogrifier
alias MobilizonWeb.API
setup_all do
HTTPoison.start()
end
@ -845,7 +847,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
other_actor = insert(:actor)
{:ok, activity, _} =
MobilizonWeb.API.Comments.create_comment(
API.Comments.create_comment(
actor.preferred_username,
"hey, @#{other_actor.preferred_username}, how are ya? #2hu"
)
@ -881,8 +883,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it adds the json-ld context and the conversation property" do
actor = insert(:actor)
{:ok, activity, _} =
MobilizonWeb.API.Comments.create_comment(actor.preferred_username, "hey")
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "hey")
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
@ -892,8 +893,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it sets the 'attributedTo' property to the actor of the object if it doesn't have one" do
actor = insert(:actor)
{:ok, activity, _} =
MobilizonWeb.API.Comments.create_comment(actor.preferred_username, "hey")
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "hey")
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
@ -903,8 +903,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it strips internal hashtag data" do
actor = insert(:actor)
{:ok, activity, _} =
MobilizonWeb.API.Comments.create_comment(actor.preferred_username, "#2hu")
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "#2hu")
expected_tag = %{
"href" => MobilizonWeb.Endpoint.url() <> "/tags/2hu",
@ -920,8 +919,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it strips internal fields" do
actor = insert(:actor)
{:ok, activity, _} =
MobilizonWeb.API.Comments.create_comment(actor.preferred_username, "#2hu")
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "#2hu")
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)

View file

@ -5,7 +5,7 @@ defmodule Mobilizon.Service.ActivityPub.UtilsTest do
import Mobilizon.Factory
alias Mobilizon.Service.ActivityPub.Utils
alias Mobilizon.Service.ActivityPub.{Converter, Utils}
alias MobilizonWeb.Endpoint
alias MobilizonWeb.Router.Helpers, as: Routes
@ -28,7 +28,7 @@ defmodule Mobilizon.Service.ActivityPub.UtilsTest do
"id" => Routes.page_url(Endpoint, :comment, reply.uuid),
"inReplyTo" => comment.url,
"attributedTo" => reply.actor.url
} == Mobilizon.Service.ActivityPub.Converters.Comment.model_to_as(reply)
} == Converter.Comment.model_to_as(reply)
end
test "comment data from map" do

View file

@ -7,6 +7,7 @@ defmodule MobilizonWeb.API.ReportTest do
alias Mobilizon.Events.{Comment, Event}
alias Mobilizon.Reports.{Note, Report}
alias Mobilizon.Service.ActivityPub.Activity
alias Mobilizon.Service.Formatter
alias Mobilizon.Users
alias Mobilizon.Users.User
@ -86,7 +87,7 @@ defmodule MobilizonWeb.API.ReportTest do
_comment_2 = insert(:comment, actor: reported)
comment = "This is really not acceptable, remote admin I don't know"
encoded_comment = Mobilizon.Service.Formatter.html_escape(comment, "text/plain")
encoded_comment = Formatter.html_escape(comment, "text/plain")
assert {:ok, %Activity{} = flag_activity, _} =
Reports.report(%{

View file

@ -3,27 +3,20 @@ defmodule MobilizonWeb.NodeInfoControllerTest do
alias Mobilizon.Config
alias MobilizonWeb.Endpoint
alias MobilizonWeb.Router.Helpers, as: Routes
test "Get node info schemas", %{conn: conn} do
conn = get(conn, node_info_path(conn, :schemas))
assert json_response(conn, 200) == %{
"links" => [
%{
"href" =>
MobilizonWeb.Router.Helpers.node_info_url(
MobilizonWeb.Endpoint,
:nodeinfo,
"2.0"
),
"href" => Routes.node_info_url(Endpoint, :nodeinfo, "2.0"),
"rel" => "http://nodeinfo.diaspora.software/ns/schema/2.0"
},
%{
"href" =>
MobilizonWeb.Router.Helpers.node_info_url(
MobilizonWeb.Endpoint,
:nodeinfo,
"2.1"
),
"href" => Routes.node_info_url(Endpoint, :nodeinfo, "2.1"),
"rel" => "http://nodeinfo.diaspora.software/ns/schema/2.1"
}
]

View file

@ -9,6 +9,7 @@ defmodule MobilizonWeb.Resolvers.AdminResolverTest do
alias Mobilizon.Users.User
alias MobilizonWeb.AbsintheHelpers
alias MobilizonWeb.API
describe "Resolver: List the action logs" do
@note_content "This a note on a report"
@ -20,12 +21,11 @@ defmodule MobilizonWeb.Resolvers.AdminResolverTest do
%Actor{} = moderator_2 = insert(:actor, user: user_moderator_2)
%Report{} = report = insert(:report)
MobilizonWeb.API.Reports.update_report_status(moderator, report, "resolved")
API.Reports.update_report_status(moderator, report, "resolved")
{:ok, %Note{} = note} =
MobilizonWeb.API.Reports.create_report_note(report, moderator_2, @note_content)
{:ok, %Note{} = note} = API.Reports.create_report_note(report, moderator_2, @note_content)
MobilizonWeb.API.Reports.delete_report_note(note, moderator_2)
API.Reports.delete_report_note(note, moderator_2)
query = """
{

View file

@ -15,6 +15,10 @@ defmodule MobilizonWeb.ChannelCase do
use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox, as: Adapter
alias Mobilizon.Storage.Repo
using do
quote do
# Import conveniences for testing with channels
@ -26,11 +30,9 @@ defmodule MobilizonWeb.ChannelCase do
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Mobilizon.Storage.Repo)
:ok = Adapter.checkout(Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Mobilizon.Storage.Repo, {:shared, self()})
end
unless tags[:async], do: Adapter.mode(Repo, {:shared, self()})
:ok
end

View file

@ -15,6 +15,11 @@ defmodule MobilizonWeb.ConnCase do
use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox, as: Adapter
alias Mobilizon.Storage.Repo
alias Mobilizon.Users.User
using do
quote do
# Import conveniences for testing with connections
@ -24,7 +29,7 @@ defmodule MobilizonWeb.ConnCase do
# The default endpoint for testing
@endpoint MobilizonWeb.Endpoint
def auth_conn(%Plug.Conn{} = conn, %Mobilizon.Users.User{} = user) do
def auth_conn(%Plug.Conn{} = conn, %User{} = user) do
{:ok, token, _claims} = MobilizonWeb.Guardian.encode_and_sign(user)
conn
@ -35,11 +40,9 @@ defmodule MobilizonWeb.ConnCase do
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Mobilizon.Storage.Repo)
:ok = Adapter.checkout(Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Mobilizon.Storage.Repo, {:shared, self()})
end
unless tags[:async], do: Adapter.mode(Repo, {:shared, self()})
{:ok, conn: Phoenix.ConnTest.build_conn()}
end

View file

@ -14,7 +14,10 @@ defmodule Mobilizon.DataCase do
use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox, as: Adapter
alias Mobilizon.Config
alias Mobilizon.Storage.Repo
using do
quote do
@ -28,11 +31,9 @@ defmodule Mobilizon.DataCase do
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Mobilizon.Storage.Repo)
:ok = Adapter.checkout(Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Mobilizon.Storage.Repo, {:shared, self()})
end
unless tags[:async], do: Adapter.mode(Repo, {:shared, self()})
:ok
end