Improve Federation boundaries

This commit is contained in:
rustra 2020-01-23 21:59:50 +01:00
parent 8ca5c0b320
commit 3577fe42e1
67 changed files with 314 additions and 227 deletions

View File

@ -44,7 +44,7 @@ config :mobilizon, MobilizonWeb.Endpoint,
# Upload configuration
config :mobilizon, MobilizonWeb.Upload,
uploader: MobilizonWeb.Uploaders.Local,
uploader: MobilizonWeb.Upload.Uploader.Local,
filters: [
MobilizonWeb.Upload.Filter.Dedupe,
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,
enabled: true,
@ -78,7 +78,7 @@ config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
config :mobilizon, MobilizonWeb.Guardian,
config :mobilizon, MobilizonWeb.Auth.Guardian,
issuer: "mobilizon",
secret_key: "ty0WM7YBE3ojvxoUQxo8AERrNpfbXnIJ82ovkPdqbUFw31T5LcK8wGjaOiReVQjo"

View File

@ -66,8 +66,8 @@ config :mobilizon, MobilizonWeb.Email.Mailer, adapter: Bamboo.LocalAdapter
# Configure your database
config :mobilizon, Mobilizon.Storage.Repo,
types: Mobilizon.Storage.PostgresTypes,
username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "postgres",
password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "postgres",
username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon",
password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon",
database: System.get_env("MOBILIZON_DATABASE_DBNAME") || "mobilizon_dev",
hostname: System.get_env("MOBILIZON_DATABASE_HOST") || "localhost",
port: System.get_env("MOBILIZON_DATABASE_PORT") || "5432",

View File

@ -24,8 +24,8 @@ config :logger,
# Configure your database
config :mobilizon, Mobilizon.Storage.Repo,
types: Mobilizon.Storage.PostgresTypes,
username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "postgres",
password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "postgres",
username: System.get_env("MOBILIZON_DATABASE_USERNAME") || "mobilizon",
password: System.get_env("MOBILIZON_DATABASE_PASSWORD") || "mobilizon",
database: System.get_env("MOBILIZON_DATABASE_DBNAME") || "mobilizon_test",
hostname: System.get_env("MOBILIZON_DATABASE_HOST") || "localhost",
pool: Ecto.Adapters.SQL.Sandbox
@ -34,7 +34,7 @@ config :mobilizon, MobilizonWeb.Email.Mailer, adapter: Bamboo.TestAdapter
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,
vcr_cassette_library_dir: "test/fixtures/vcr_cassettes"

View File

@ -221,7 +221,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
%{"type" => "Update", "object" => %{"type" => "Event"} = object, "actor" => _actor} =
update_data
) do
with actor <- Utils.get_actor(update_data),
with actor <- Utils.get_actor(update_data),
{:ok, %Actor{url: actor_url}} <- Actors.get_actor_by_url(actor),
{:ok, %Event{} = old_event} <-
object |> Utils.get_url() |> ActivityPub.fetch_object_from_url(),
@ -289,7 +289,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
with actor <- Utils.get_actor(data),
{:ok, %Actor{url: actor_url}} <- Actors.get_actor_by_url(actor),
object_id <- Utils.get_url(object),
{:origin_check, true} <- {:origin_check, Utils.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, activity, object} <- ActivityPub.delete(object, false) do
{:ok, activity, object}

View File

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

View File

@ -4,9 +4,19 @@ defmodule Mobilizon.Admin do
"""
import Ecto.Query
import EctoEnum
alias Mobilizon.Actors.Actor
alias Mobilizon.{Admin, Users}
alias Mobilizon.Admin.ActionLog
alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.User
defenum(ActionLogAction, [
"update",
"create",
"delete"
])
@doc """
Creates a action_log.
@ -28,8 +38,37 @@ defmodule Mobilizon.Admin do
|> Repo.all()
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()
defp list_action_logs_query do
from(r in ActionLog, preload: [:actor], order_by: [desc: :id])
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

@ -7,10 +7,11 @@ defmodule Mobilizon.Events do
import Ecto.Query
import EctoEnum
alias Ecto.{Multi, Changeset}
import Mobilizon.Storage.Ecto
alias Ecto.{Multi, Changeset}
alias Mobilizon.Actors.Actor
alias Mobilizon.Addresses.Address
@ -331,14 +332,14 @@ defmodule Mobilizon.Events do
|> Repo.transaction() do
Cachex.del(:ics, "event_#{new_event.uuid}")
Email.Events.calculate_event_diff_and_send_notifications(
Email.Event.calculate_event_diff_and_send_notifications(
old_event,
new_event,
changes
)
unless new_event.draft,
do: BuildSearch.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)}
end

View File

@ -13,6 +13,8 @@ defmodule Mobilizon.Users do
alias Mobilizon.Storage.{Page, Repo}
alias Mobilizon.Users.User
alias MobilizonWeb.Auth
@type tokens :: %{
required(:access_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()}
def generate_access_token(user) do
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}
end
end
@ -258,7 +260,7 @@ defmodule Mobilizon.Users do
@spec generate_refresh_token(User.t()) :: {:ok, String.t()}
def generate_refresh_token(user) do
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}
end
end

View File

@ -3,12 +3,10 @@ defmodule MobilizonWeb.API.Reports do
API for Reports.
"""
import Mobilizon.Service.Admin.ActionLog
alias Mobilizon.Actors.Actor
alias Mobilizon.{Admin, Users}
alias Mobilizon.Reports, as: ReportsAction
alias Mobilizon.Reports.{Note, Report, ReportStatus}
alias Mobilizon.Users
alias Mobilizon.Users.User
alias Mobilizon.Federation.ActivityPub
@ -34,7 +32,7 @@ defmodule MobilizonWeb.API.Reports do
with {:valid_state, true} <-
{:valid_state, ReportStatus.valid_value?(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}
else
{:valid_state, false} -> {:error, "Unsupported state"}
@ -58,7 +56,7 @@ defmodule MobilizonWeb.API.Reports do
"moderator_id" => moderator_id,
"content" => content
}),
{:ok, _} <- log_action(moderator, "create", note) do
{:ok, _} <- Admin.log_action(moderator, "create", note) do
{:ok, note}
else
{:role, false} ->
@ -79,7 +77,7 @@ defmodule MobilizonWeb.API.Reports do
{:role, true} <- {:role, role in [:administrator, :moderator]},
{:ok, %Note{} = note} <-
Mobilizon.Reports.delete_note(note),
{:ok, _} <- log_action(moderator, "delete", note) do
{:ok, _} <- Admin.log_action(moderator, "delete", note) do
{:ok, note}
else
{:role, false} ->

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
defmodule MobilizonWeb.Cache.ActivityPub do
@moduledoc """
The ActivityPub related functions.
ActivityPub related cache.
"""
alias Mobilizon.{Actors, Events, Tombstone}
@ -9,8 +9,8 @@ defmodule MobilizonWeb.Cache.ActivityPub do
alias Mobilizon.Federation.ActivityPub.Relay
alias MobilizonWeb.Router.Helpers, as: Routes
alias MobilizonWeb.Endpoint
alias MobilizonWeb.Router.Helpers, as: Routes
@cache :activity_pub

View File

@ -8,7 +8,7 @@ defmodule MobilizonWeb.GraphQLSocket do
def connect(%{"token" => token}, socket) do
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
authed_socket =
Absinthe.Phoenix.Socket.put_options(socket,

View File

@ -3,8 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/web/activity_pub/activity_pub_controller.ex
defmodule Mobilizon.Federation.ActivityPubController do
use Mobilizon.Federation, :controller
defmodule MobilizonWeb.ActivityPubController do
use MobilizonWeb, :controller
alias Mobilizon.{Actors, Config}
alias Mobilizon.Actors.Actor
@ -19,7 +19,7 @@ defmodule Mobilizon.Federation.ActivityPubController do
action_fallback(:errors)
plug(Mobilizon.Federation.Plugs.Federating when action in [:inbox, :relay])
plug(MobilizonWeb.Plugs.Federating when action in [:inbox, :relay])
plug(:relay_active? when action in [:relay])
def relay_active?(conn, _) do

View File

@ -12,7 +12,7 @@ defmodule MobilizonWeb.WebFingerController do
alias Mobilizon.Federation.WebFinger
plug(Mobilizon.Federation.Plugs.Federating)
plug(MobilizonWeb.Plugs.Federating)
@doc """
Provides /.well-known/host-meta

View File

@ -149,9 +149,9 @@ defmodule MobilizonWeb.Email.User do
_ ->
case Timex.before?(
Timex.shift(Map.get(user, key), hours: 1),
DateTime.utc_now() |> DateTime.truncate(:second)
) do
Timex.shift(Map.get(user, key), hours: 1),
DateTime.utc_now() |> DateTime.truncate(:second)
) do
true ->
:ok

View File

@ -3,7 +3,7 @@
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mobilizon.Federation.Plugs.Federating do
defmodule MobilizonWeb.Plugs.Federating do
@moduledoc """
Restrict ActivityPub routes when not federating
"""

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/plugs/http_signature.ex
defmodule Mobilizon.Federation.Plugs.HTTPSignatures do
defmodule MobilizonWeb.Plugs.HTTPSignatures do
@moduledoc """
Plug to check HTTP Signatures on every incoming request
"""

View File

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

View File

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

View File

@ -10,7 +10,7 @@ defmodule MobilizonWeb.Resolvers.User do
alias Mobilizon.Storage.Repo
alias Mobilizon.Users.User
alias MobilizonWeb.Email
alias MobilizonWeb.{Auth, Email}
require Logger
@ -94,9 +94,9 @@ defmodule MobilizonWeb.Resolvers.User do
},
_context
) 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}} <-
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, %{access_token: exchanged_token, refresh_token: refresh_token}}
else

View File

@ -6,7 +6,7 @@ defmodule MobilizonWeb.Router do
pipeline :graphql do
# plug(:accepts, ["json"])
plug(MobilizonWeb.AuthPipeline)
plug(MobilizonWeb.Auth.Pipeline)
end
pipeline :well_known do
@ -14,13 +14,13 @@ defmodule MobilizonWeb.Router do
end
pipeline :activity_pub_signature do
plug(Mobilizon.Federation.Plugs.HTTPSignatures)
plug(Mobilizon.Federation.Plugs.MappedSignatureToIdentity)
plug(MobilizonWeb.Plugs.HTTPSignatures)
plug(MobilizonWeb.Plugs.MappedSignatureToIdentity)
end
pipeline :relay do
plug(Mobilizon.Federation.Plugs.HTTPSignatures)
plug(Mobilizon.Federation.Plugs.MappedSignatureToIdentity)
plug(MobilizonWeb.Plugs.HTTPSignatures)
plug(MobilizonWeb.Plugs.MappedSignatureToIdentity)
plug(:accepts, ["activity-json", "json"])
end
@ -58,7 +58,7 @@ defmodule MobilizonWeb.Router do
)
end
forward("/graphiql", Absinthe.Plug.GraphiQL, schema: MobilizonWeb.Schema)
## FEDERATION
scope "/.well-known", MobilizonWeb do
pipe_through(:well_known)
@ -69,28 +69,6 @@ defmodule MobilizonWeb.Router do
get("/nodeinfo/:version", NodeInfoController, :nodeinfo)
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
pipe_through(:activity_pub_and_html)
pipe_through(:activity_pub_signature)
@ -121,6 +99,34 @@ defmodule MobilizonWeb.Router do
post("/inbox", ActivityPubController, :inbox)
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
pipe_through(:remote_media)

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/mime.ex
defmodule MobilizonWeb.MIME do
defmodule MobilizonWeb.Upload.MIME do
@moduledoc """
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:
* `MobilizonWeb.Uploaders.Uploader`
* `MobilizonWeb.Upload.Uploader`
* `MobilizonWeb.Upload.Filter`
"""
@ -36,7 +36,7 @@ defmodule MobilizonWeb.Upload do
alias Mobilizon.Config
alias MobilizonWeb.{MIME, Upload, Uploaders}
alias MobilizonWeb.Upload.{Filter, MIME, Uploader}
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} <- Upload.Filter.filter(opts.filters, upload),
{:ok, url_spec} <- Uploaders.Uploader.put_file(opts.uploader, upload) do
{:ok, upload} <- Filter.filter(opts.filters, upload),
{:ok, url_spec} <- Uploader.put_file(opts.uploader, upload) do
{:ok,
%{
name: Map.get(opts, :description) || upload.name,
@ -92,7 +92,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
Uploaders.Uploader.remove_file(opts.uploader, path)
Uploader.remove_file(opts.uploader, path)
else
%URI{} = _uri ->
{:error, "URL doesn't match pattern"}

View File

@ -3,12 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only
# 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 """
Local uploader for files
"""
@behaviour MobilizonWeb.Uploaders.Uploader
@behaviour MobilizonWeb.Upload.Uploader
alias Mobilizon.Config

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
# 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 """
Defines the contract to put and get an uploaded file to any backend.
"""

View File

@ -1,39 +0,0 @@
defmodule Mobilizon.Service.Admin.ActionLog do
@moduledoc """
Module to handle action log creations.
"""
alias Mobilizon.Actors.Actor
alias Mobilizon.{Admin, Users}
alias Mobilizon.Admin.ActionLog
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

@ -14,4 +14,3 @@ defmodule Mobilizon.Service.Formatter.HTML do
def filter_tags(html), do: Scrubber.scrub(html, DefaultScrubbler)
end

View File

@ -9,6 +9,7 @@ defmodule Mobilizon.Service.Workers.Helper do
"""
alias Mobilizon.Config
alias Mobilizon.Service.Workers.Helper
alias Mobilizon.Storage.Repo
def worker_args(queue) do
@ -40,7 +41,7 @@ defmodule Mobilizon.Service.Workers.Helper do
def enqueue(operation, params, worker_args \\ []) do
params = Map.merge(%{"op" => operation}, params)
queue_atom = String.to_existing_atom(unquote(queue))
worker_args = worker_args ++ __MODULE__.worker_args(queue_atom)
worker_args = worker_args ++ Helper.worker_args(queue_atom)
unquote(caller_module)
|> apply(:new, [params, worker_args])

141
mix.exs
View File

@ -181,6 +181,8 @@ defmodule Mobilizon.Mixfile do
Mobilizon.Actors.Member,
Mobilizon.Addresses,
Mobilizon.Addresses.Address,
Mobilizon.Admin,
Mobilizon.Admin.ActionLog,
Mobilizon.Events,
Mobilizon.Events.Event,
Mobilizon.Events.Comment,
@ -190,7 +192,7 @@ defmodule Mobilizon.Mixfile do
Mobilizon.Events.Tag,
Mobilizon.Events.TagRelations,
Mobilizon.Events.Track,
Mobilizon.Event.EventCategory,
Mobilizon.Events.EventCategory,
Mobilizon.Events.CommentVisibility,
Mobilizon.Events.EventStatus,
Mobilizon.Events.EventVisibility,
@ -199,111 +201,184 @@ defmodule Mobilizon.Mixfile do
Mobilizon.Events.Tag.TitleSlug,
Mobilizon.Events.Tag.TitleSlug.Type,
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.User,
Mobilizon.Users.UserRole,
Mobilizon.Users.Guards,
Mobilizon.Storage.Ecto,
Mobilizon.Storage.Repo,
Mobilizon.Federation.ActivityPub.Activity
],
APIs: [
MobilizonWeb.API.Comments,
MobilizonWeb.API.Events,
MobilizonWeb.API.Follows,
MobilizonWeb.API.Groups,
MobilizonWeb.API.Participations,
MobilizonWeb.API.Reports,
MobilizonWeb.API.Search,
MobilizonWeb.API.Utils
],
Web: [
MobilizonWeb,
MobilizonWeb.PageView,
MobilizonWeb.Endpoint,
MobilizonWeb.Router,
MobilizonWeb.Router.Helpers,
MobilizonWeb.AuthErrorHandler,
MobilizonWeb.AuthPipeline,
MobilizonWeb.Cache,
MobilizonWeb.ChangesetView,
MobilizonWeb.Context,
MobilizonWeb.Endpoint,
MobilizonWeb.ErrorHelpers,
MobilizonWeb.ErrorView,
MobilizonWeb.Plugs.UploadedMedia,
MobilizonWeb.FallbackController,
MobilizonWeb.FeedController,
MobilizonWeb.Gettext,
MobilizonWeb.Guardian,
MobilizonWeb.Guardian.Plug,
MobilizonWeb.JsonLD.ObjectView,
MobilizonWeb.MediaProxyController,
MobilizonWeb.PageController,
MobilizonWeb.Uploaders.Avatar,
MobilizonWeb.Uploaders.Category,
MobilizonWeb.Uploaders.Category.Type
MobilizonWeb.ChangesetView,
MobilizonWeb.JsonLD.ObjectView,
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: [
Mobilizon.Service.Geospatial,
Mobilizon.Service.Geospatial.Addok,
Mobilizon.Service.Geospatial.GoogleMaps,
Mobilizon.Service.Geospatial.MapQuest,
Mobilizon.Service.Geospatial.Mimirsbrunn,
Mobilizon.Service.Geospatial.Nominatim,
Mobilizon.Service.Geospatial.Pelias,
Mobilizon.Service.Geospatial.Photon,
Mobilizon.Service.Geospatial.Provider
],
Localization: [
Mobilizon.Cldr,
MobilizonWeb.Gettext
],
GraphQL: [
MobilizonWeb.GraphQLSocket,
MobilizonWeb.Resolvers.Address,
MobilizonWeb.Resolvers.Admin,
MobilizonWeb.Resolvers.Comment,
MobilizonWeb.Resolvers.Config,
MobilizonWeb.Resolvers.Event,
MobilizonWeb.Resolvers.FeedToken,
MobilizonWeb.Resolvers.Group,
MobilizonWeb.Resolvers.Member,
MobilizonWeb.Resolvers.Person,
MobilizonWeb.Resolvers.Picture,
MobilizonWeb.Resolvers.Report,
MobilizonWeb.Resolvers.Search,
MobilizonWeb.Resolvers.Tag,
MobilizonWeb.Resolvers.User,
MobilizonWeb.Schema,
MobilizonWeb.Schema.ActorInterface,
MobilizonWeb.Schema.Actors.ApplicationType,
MobilizonWeb.Schema.Actors.FollowerType,
MobilizonWeb.Schema.Actors.GroupType,
MobilizonWeb.Schema.Actors.MemberType,
MobilizonWeb.Schema.Actors.PersonType,
MobilizonWeb.Schema.AddressType,
MobilizonWeb.Schema.AdminType,
MobilizonWeb.Schema.CommentType,
MobilizonWeb.Schema.Custom.Point,
MobilizonWeb.Schema.Custom.UUID,
MobilizonWeb.Schema.ConfigType,
MobilizonWeb.Schema.EventType,
MobilizonWeb.Schema.Events.FeedTokenType,
MobilizonWeb.Schema.Events.ParticipantType,
MobilizonWeb.Schema.PictureType,
MobilizonWeb.Schema.ReportType,
MobilizonWeb.Schema.SearchType,
MobilizonWeb.Schema.SortType,
MobilizonWeb.Schema.TagType,
MobilizonWeb.Schema.UserType,
MobilizonWeb.Schema.Utils
MobilizonWeb.Schema.Utils,
MobilizonWeb.Schema.Custom.Point,
MobilizonWeb.Schema.Custom.UUID
],
ActivityPub: [
Mobilizon.Federation.ActivityPub,
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,
Mobilizon.Federation.Plugs.HTTPSignatures,
MobilizonWeb.ActivityPub.ActorView,
MobilizonWeb.ActivityPub.ObjectView,
MobilizonWeb.Plugs.Federating,
MobilizonWeb.Plugs.HTTPSignatures,
MobilizonWeb.Plugs.MappedSignatureToIdentity,
MobilizonWeb.ActivityPubController,
MobilizonWeb.NodeInfoController,
MobilizonWeb.WebFingerController,
MobilizonWeb.NodeInfoController
MobilizonWeb.ActivityPub.ActorView,
MobilizonWeb.ActivityPub.ObjectView
],
Services: [
Mobilizon.Service.EmailChecker,
Mobilizon.Service.Export.Feed,
Mobilizon.Service.Export.ICalendar,
Mobilizon.Service.Metadata,
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: [
Mobilizon.Application,
Mobilizon.Config,
Mobilizon.Crypto,
Mobilizon.Factory,
MobilizonWeb.Email.Mailer,
MobilizonWeb.Email.User,
MobilizonWeb.EmailView
Mobilizon.Storage.Ecto,
Mobilizon.Storage.Page,
Mobilizon.Storage.Repo
]
]
end

View File

@ -14,6 +14,8 @@ defmodule Mobilizon.ActorsTest do
alias Mobilizon.Federation.ActivityPub
alias MobilizonWeb.Upload.Uploader
describe "actors" do
@valid_attrs %{
summary: "some description",
@ -241,12 +243,12 @@ defmodule Mobilizon.ActorsTest do
%URI{path: "/media/" <> banner_path} = URI.parse(banner_url)
assert File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> avatar_path
)
assert File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> banner_path
)
@ -271,12 +273,12 @@ defmodule Mobilizon.ActorsTest do
refute actor.suspended
refute File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> avatar_path
)
assert File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> banner_path
)
end
@ -300,12 +302,12 @@ defmodule Mobilizon.ActorsTest do
%URI{path: "/media/" <> banner_path} = URI.parse(banner_url)
assert File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> avatar_path
)
assert File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> banner_path
)
@ -334,12 +336,12 @@ defmodule Mobilizon.ActorsTest do
assert %Tombstone{} = Tombstone.find_tombstone(comment1_url)
refute File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> avatar_path
)
refute File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> banner_path
)
end

View File

@ -6,8 +6,8 @@ defmodule Mobilizon.Service.Admin.ActionLogTest do
use Mobilizon.DataCase
import Mobilizon.Factory
import Mobilizon.Service.Admin.ActionLog
alias Mobilizon.Admin
alias Mobilizon.Admin.ActionLog
alias Mobilizon.Reports.{Note, Report}
@ -27,7 +27,7 @@ defmodule Mobilizon.Service.Admin.ActionLogTest do
target_id: report_id,
action: :update,
actor: moderator
}} = log_action(moderator, "update", report)
}} = Admin.log_action(moderator, "update", report)
end
test "log the creation of a report note", %{moderator: moderator} do
@ -40,7 +40,7 @@ defmodule Mobilizon.Service.Admin.ActionLogTest do
target_id: note_id,
action: :create,
actor: moderator
}} = log_action(moderator, "create", report)
}} = Admin.log_action(moderator, "create", report)
end
end
end

View File

@ -5,6 +5,8 @@ defmodule Mobilizon.MediaTest do
alias Mobilizon.{Config, Media}
alias MobilizonWeb.Upload.Uploader
describe "media" do
setup [:ensure_local_uploader]
alias Mobilizon.Media.Picture
@ -49,7 +51,7 @@ defmodule Mobilizon.MediaTest do
%URI{path: "/media/" <> path} = URI.parse(picture.file.url)
assert File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> path
)
@ -57,7 +59,7 @@ defmodule Mobilizon.MediaTest do
assert_raise Ecto.NoResultsError, fn -> Media.get_picture!(picture.id) end
refute File.exists?(
Config.get!([MobilizonWeb.Uploaders.Local, :uploads]) <>
Config.get!([Uploader.Local, :uploads]) <>
"/" <> path
)
end

View File

@ -3,10 +3,10 @@
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mobilizon.Federation.Plug.FederatingTest do
defmodule MobilizonWeb.Plug.FederatingTest do
use MobilizonWeb.ConnCase
alias Mobilizon.Federation.Plugs.Federating
alias MobilizonWeb.Plugs.Federating
test "returns and halt the conn when federating is disabled" do
Mobilizon.Config.put([:instance, :federating], false)

View File

@ -3,7 +3,7 @@
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mobilizon.Federation.Plugs.MappedSignatureToIdentityTest do
defmodule MobilizonWeb.Plugs.MappedSignatureToIdentityTest do
use MobilizonWeb.ConnCase
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney

View File

@ -158,7 +158,11 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
{id, ""} = json_response(res, 200)["data"]["createEvent"]["id"] |> Integer.parse()
assert_enqueued