Merge remote-tracking branch 'remotes/origin/develop' into ostatus-controller-no-auth-check-on-non-federating-instances

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Ivan Tashkinov 2020-10-28 19:03:40 +03:00
commit ba50dc05a8
54 changed files with 629 additions and 183 deletions

View file

@ -100,7 +100,7 @@ defmodule Pleroma.Application do
] ++
task_children(@env) ++
dont_run_in_test(@env) ++
chat_child(@env, chat_enabled?()) ++
chat_child(chat_enabled?()) ++
[
Pleroma.Web.Endpoint,
Pleroma.Gopher.Server
@ -151,7 +151,10 @@ defmodule Pleroma.Application do
Pleroma.Web.Endpoint.MetricsExporter.setup()
Pleroma.Web.Endpoint.PipelineInstrumenter.setup()
Pleroma.Web.Endpoint.Instrumenter.setup()
# Note: disabled until prometheus-phx is integrated into prometheus-phoenix:
# Pleroma.Web.Endpoint.Instrumenter.setup()
PrometheusPhx.setup()
end
defp cachex_children do
@ -202,11 +205,14 @@ defmodule Pleroma.Application do
]
end
defp chat_child(_env, true) do
[Pleroma.Web.ChatChannel.ChatChannelState]
defp chat_child(true) do
[
Pleroma.Web.ChatChannel.ChatChannelState,
{Phoenix.PubSub, [name: Pleroma.PubSub, adapter: Phoenix.PubSub.PG2]}
]
end
defp chat_child(_, _), do: []
defp chat_child(_), do: []
defp task_children(:test) do
[

View file

@ -0,0 +1,19 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Helpers.InetHelper do
def parse_address(ip) when is_tuple(ip) do
{:ok, ip}
end
def parse_address(ip) when is_binary(ip) do
ip
|> String.to_charlist()
|> parse_address()
end
def parse_address(ip) do
:inet.parse_address(ip)
end
end

View file

@ -426,7 +426,6 @@ defmodule Pleroma.User do
params,
[
:bio,
:name,
:emoji,
:ap_id,
:inbox,
@ -455,7 +454,9 @@ defmodule Pleroma.User do
:accepts_chat_messages
]
)
|> validate_required([:name, :ap_id])
|> cast(params, [:name], empty_values: [])
|> validate_required([:ap_id])
|> validate_required([:name], trim: false)
|> unique_constraint(:nickname)
|> validate_format(:nickname, @email_regex)
|> validate_length(:bio, max: bio_limit)
@ -765,6 +766,16 @@ defmodule Pleroma.User do
follow_all(user, autofollowed_users)
end
defp autofollowing_users(user) do
candidates = Config.get([:instance, :autofollowing_nicknames])
User.Query.build(%{nickname: candidates, local: true, deactivated: false})
|> Repo.all()
|> Enum.each(&follow(&1, user, :follow_accept))
{:ok, :success}
end
@doc "Inserts provided changeset, performs post-registration actions (confirmation email sending etc.)"
def register(%Ecto.Changeset{} = changeset) do
with {:ok, user} <- Repo.insert(changeset) do
@ -774,6 +785,7 @@ defmodule Pleroma.User do
def post_register_action(%User{} = user) do
with {:ok, user} <- autofollow_users(user),
{:ok, _} <- autofollowing_users(user),
{:ok, user} <- set_cache(user),
{:ok, _} <- send_welcome_email(user),
{:ok, _} <- send_welcome_message(user),

View file

@ -172,7 +172,7 @@ defmodule Pleroma.Web do
def channel do
quote do
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
use Phoenix.Channel
import Phoenix.Channel
import Pleroma.Web.Gettext
end
end

View file

@ -827,7 +827,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
query =
from([activity] in query,
where: fragment("not (? = ANY(?))", activity.actor, ^mutes),
where: fragment("not (?->'to' \\?| ?)", activity.data, ^mutes)
where:
fragment(
"not (?->'to' \\?| ?) or ? = ?",
activity.data,
^mutes,
activity.actor,
^user.ap_id
)
)
unless opts[:skip_preload] do
@ -1371,6 +1378,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
{:ok, data} <- user_data_from_user_object(data) do
{:ok, maybe_update_follow_information(data)}
else
# If this has been deleted, only log a debug and not an error
{:error, "Object has been deleted" = e} ->
Logger.debug("Could not decode user at fetch #{ap_id}, #{inspect(e)}")
{:error, e}

View file

@ -414,7 +414,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
object =
object
|> Map.merge(Map.take(params, ["to", "cc"]))
|> Map.put("attributedTo", user.ap_id())
|> Map.put("attributedTo", user.ap_id)
|> Transmogrifier.fix_object()
ActivityPub.create(%{
@ -458,7 +458,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
%{assigns: %{user: %User{nickname: nickname} = user}} = conn,
%{"nickname" => nickname} = params
) do
actor = user.ap_id()
actor = user.ap_id
params =
params
@ -525,19 +525,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
{new_user, for_user}
end
@doc """
Endpoint based on <https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload>
Parameters:
- (required) `file`: data of the media
- (optionnal) `description`: description of the media, intended for accessibility
Response:
- HTTP Code: 201 Created
- HTTP Body: ActivityPub object to be inserted into another's `attachment` field
Note: Will not point to a URL with a `Location` header because no standalone Activity has been created.
"""
def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do
with {:ok, object} <-
ActivityPub.upload(

View file

@ -242,9 +242,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
end)
end
@doc """
Publishes an activity to all relevant peers.
"""
# Publishes an activity to all relevant peers.
def publish(%User{} = actor, %Activity{} = activity) do
public = is_public?(activity)

View file

@ -306,6 +306,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
streamables =
[[actor, recipient], [recipient, actor]]
|> Enum.uniq()
|> Enum.map(fn [user, other_user] ->
if user.local do
{:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)

View file

@ -40,6 +40,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> fix_in_reply_to(options)
|> fix_emoji
|> fix_tag
|> set_sensitive
|> fix_content_map
|> fix_addressing
|> fix_summary
@ -313,19 +314,21 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
tags =
tag
|> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
|> Enum.map(fn data -> String.slice(data["name"], 1..-1) end)
|> Enum.map(fn %{"name" => name} ->
name
|> String.slice(1..-1)
|> String.downcase()
end)
Map.put(object, "tag", tag ++ tags)
end
def fix_tag(%{"tag" => %{"type" => "Hashtag", "name" => hashtag} = tag} = object) do
combined = [tag, String.slice(hashtag, 1..-1)]
Map.put(object, "tag", combined)
def fix_tag(%{"tag" => %{} = tag} = object) do
object
|> Map.put("tag", [tag])
|> fix_tag
end
def fix_tag(%{"tag" => %{} = tag} = object), do: Map.put(object, "tag", [tag])
def fix_tag(object), do: object
# content map usually only has one language so this will do for now.
@ -927,7 +930,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
Map.put(object, "conversation", object["context"])
end
def set_sensitive(%{"sensitive" => true} = object) do
def set_sensitive(%{"sensitive" => _} = object) do
object
end

View file

@ -52,7 +52,7 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
end
def render("index_notes.json", %{notes: notes}) when is_list(notes) do
Enum.map(notes, &render(__MODULE__, "show_note.json", &1))
Enum.map(notes, &render(__MODULE__, "show_note.json", Map.from_struct(&1)))
end
def render("index_notes.json", _), do: []

View file

@ -274,7 +274,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def format_input(text, format, options \\ [])
@doc """
Formatting text to plain text.
Formatting text to plain text, BBCode, HTML, or Markdown
"""
def format_input(text, "text/plain", options) do
text
@ -285,9 +285,6 @@ defmodule Pleroma.Web.CommonAPI.Utils do
end).()
end
@doc """
Formatting text as BBCode.
"""
def format_input(text, "text/bbcode", options) do
text
|> String.replace(~r/\r/, "")
@ -297,18 +294,12 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|> Formatter.linkify(options)
end
@doc """
Formatting text to html.
"""
def format_input(text, "text/html", options) do
text
|> Formatter.html_escape("text/html")
|> Formatter.linkify(options)
end
@doc """
Formatting text to markdown.
"""
def format_input(text, "text/markdown", options) do
text
|> Formatter.mentions_escape(options)

View file

@ -7,8 +7,12 @@ defmodule Pleroma.Web.Endpoint do
require Pleroma.Constants
alias Pleroma.Config
socket("/socket", Pleroma.Web.UserSocket)
plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint])
plug(Pleroma.Web.Plugs.SetLocalePlug)
plug(CORSPlug)
plug(Pleroma.Web.Plugs.HTTPSecurityPlug)
@ -86,19 +90,19 @@ defmodule Pleroma.Web.Endpoint do
plug(Plug.Parsers,
parsers: [
:urlencoded,
{:multipart, length: {Pleroma.Config, :get, [[:instance, :upload_limit]]}},
{:multipart, length: {Config, :get, [[:instance, :upload_limit]]}},
:json
],
pass: ["*/*"],
json_decoder: Jason,
length: Pleroma.Config.get([:instance, :upload_limit]),
length: Config.get([:instance, :upload_limit]),
body_reader: {Pleroma.Web.Plugs.DigestPlug, :read_body, []}
)
plug(Plug.MethodOverride)
plug(Plug.Head)
secure_cookies = Pleroma.Config.get([__MODULE__, :secure_cookie_flag])
secure_cookies = Config.get([__MODULE__, :secure_cookie_flag])
cookie_name =
if secure_cookies,
@ -106,7 +110,7 @@ defmodule Pleroma.Web.Endpoint do
else: "pleroma_key"
extra =
Pleroma.Config.get([__MODULE__, :extra_cookie_attrs])
Config.get([__MODULE__, :extra_cookie_attrs])
|> Enum.join(";")
# The session will be stored in the cookie and signed,
@ -116,7 +120,7 @@ defmodule Pleroma.Web.Endpoint do
Plug.Session,
store: :cookie,
key: cookie_name,
signing_salt: Pleroma.Config.get([__MODULE__, :signing_salt], "CqaoopA2"),
signing_salt: Config.get([__MODULE__, :signing_salt], "CqaoopA2"),
http_only: true,
secure: secure_cookies,
extra: extra
@ -136,8 +140,34 @@ defmodule Pleroma.Web.Endpoint do
use Prometheus.PlugExporter
end
defmodule MetricsExporterCaller do
@behaviour Plug
def init(opts), do: opts
def call(conn, opts) do
prometheus_config = Application.get_env(:prometheus, MetricsExporter, [])
ip_whitelist = List.wrap(prometheus_config[:ip_whitelist])
cond do
!prometheus_config[:enabled] ->
conn
ip_whitelist != [] and
!Enum.find(ip_whitelist, fn ip ->
Pleroma.Helpers.InetHelper.parse_address(ip) == {:ok, conn.remote_ip}
end) ->
conn
true ->
MetricsExporter.call(conn, opts)
end
end
end
plug(PipelineInstrumenter)
plug(MetricsExporter)
plug(MetricsExporterCaller)
plug(Pleroma.Web.Router)

View file

@ -24,7 +24,7 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
redirect(conn, to: local_mastodon_root_path(conn))
end
@doc "Local Mastodon FE login init action"
# Local Mastodon FE login init action
def login(conn, %{"code" => auth_token}) do
with {:ok, app} <- get_or_make_app(),
{:ok, auth} <- Authorization.get_by_token(app, auth_token),
@ -35,7 +35,7 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
end
end
@doc "Local Mastodon FE callback action"
# Local Mastodon FE callback action
def login(conn, _) do
with {:ok, app} <- get_or_make_app() do
path =

View file

@ -127,9 +127,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
@doc """
POST /api/v1/statuses
Creates a scheduled status when `scheduled_at` param is present and it's far enough
"""
# Creates a scheduled status when `scheduled_at` param is present and it's far enough
def create(
%{
assigns: %{user: user},
@ -160,11 +159,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
end
end
@doc """
POST /api/v1/statuses
Creates a regular status
"""
# Creates a regular status
def create(%{assigns: %{user: user}, body_params: %{status: _} = params} = conn, _) do
params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])

View file

@ -30,7 +30,7 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.Http do
{:ok, %{status: status} = env} when 400 <= status and status < 500 ->
{:error, env}
{:error, error} = error ->
{:error, _} = error ->
error
_ ->

View file

@ -34,22 +34,26 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
end
def call(conn, opts) do
frontend_type = Map.get(opts, :frontend_type, :primary)
path = file_path("", frontend_type)
if path do
conn
|> call_static(opts, path)
with false <- invalid_path?(conn.path_info),
frontend_type <- Map.get(opts, :frontend_type, :primary),
path when not is_nil(path) <- file_path("", frontend_type) do
call_static(conn, opts, path)
else
conn
_ ->
conn
end
end
defp call_static(conn, opts, from) do
opts =
opts
|> Map.put(:from, from)
defp invalid_path?(list) do
invalid_path?(list, :binary.compile_pattern(["/", "\\", ":", "\0"]))
end
defp invalid_path?([h | _], _match) when h in [".", "..", ""], do: true
defp invalid_path?([h | t], match), do: String.contains?(h, match) or invalid_path?(t)
defp invalid_path?([], _match), do: false
defp call_static(conn, opts, from) do
opts = Map.put(opts, :from, from)
Plug.Static.call(conn, opts)
end
end

View file

@ -228,7 +228,7 @@
<body>
<div class="container">
<h1><%= Pleroma.Config.get([:instance, :name]) %></h1>
<%= render @view_module, @view_template, assigns %>
<%= @inner_content %>
</div>
</body>
</html>

View file

@ -181,7 +181,7 @@
</div>
</div>
<% end %>
<%= render @view_module, @view_template, assigns %>
<%= @inner_content %>
</td>
</tr>

View file

@ -10,7 +10,7 @@ video, audio {
}
</style>
<%= render @view_module, @view_template, assigns %>
<%= @inner_content %>
</body>
</html>

View file

@ -9,7 +9,7 @@
</head>
<body>
<div class="container">
<%= render @view_module, @view_template, assigns %>
<%= @inner_content %>
</div>
</body>
</html>