Merge branch 'develop' into 'improve_upgrade_user_from_ap_id'

# Conflicts:
#   config/config.exs
#   docs/config.md
This commit is contained in:
lambda 2019-04-08 09:18:01 +00:00
commit b4da2bc1d0
33 changed files with 1156 additions and 41 deletions

View file

@ -25,6 +25,26 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|> json(nickname)
end
def user_follow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do
with %User{} = follower <- User.get_by_nickname(follower_nick),
%User{} = followed <- User.get_by_nickname(followed_nick) do
User.follow(follower, followed)
end
conn
|> json("ok")
end
def user_unfollow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do
with %User{} = follower <- User.get_by_nickname(follower_nick),
%User{} = followed <- User.get_by_nickname(followed_nick) do
User.unfollow(follower, followed)
end
conn
|> json("ok")
end
def user_create(
conn,
%{"nickname" => nickname, "email" => email, "password" => password}

View file

@ -70,6 +70,26 @@ defmodule Pleroma.Web.Endpoint do
extra: "SameSite=Strict"
)
# Note: the plug and its configuration is compile-time this can't be upstreamed yet
if proxies = Pleroma.Config.get([__MODULE__, :reverse_proxies]) do
plug(RemoteIp, proxies: proxies)
end
defmodule Instrumenter do
use Prometheus.PhoenixInstrumenter
end
defmodule PipelineInstrumenter do
use Prometheus.PlugPipelineInstrumenter
end
defmodule MetricsExporter do
use Prometheus.PlugExporter
end
plug(PipelineInstrumenter)
plug(MetricsExporter)
plug(Pleroma.Web.Router)
@doc """

View file

@ -5,6 +5,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
alias Pleroma.Activity
alias Pleroma.Notification
alias Pleroma.Pagination
alias Pleroma.ScheduledActivity
alias Pleroma.User
def get_followers(user, params \\ %{}) do
@ -28,6 +29,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
|> Pagination.fetch_paginated(params)
end
def get_scheduled_activities(user, params \\ %{}) do
user
|> ScheduledActivity.for_user_query()
|> Pagination.fetch_paginated(params)
end
defp cast_params(params) do
param_types = %{
exclude_types: {:array, :string}

View file

@ -5,12 +5,14 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller
alias Ecto.Changeset
alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.Filter
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.ScheduledActivity
alias Pleroma.Stats
alias Pleroma.User
alias Pleroma.Web
@ -25,6 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
alias Pleroma.Web.MastodonAPI.MastodonView
alias Pleroma.Web.MastodonAPI.NotificationView
alias Pleroma.Web.MastodonAPI.ReportView
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.MediaProxy
alias Pleroma.Web.OAuth.App
@ -364,6 +367,55 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
end
def scheduled_statuses(%{assigns: %{user: user}} = conn, params) do
with scheduled_activities <- MastodonAPI.get_scheduled_activities(user, params) do
conn
|> add_link_headers(:scheduled_statuses, scheduled_activities)
|> put_view(ScheduledActivityView)
|> render("index.json", %{scheduled_activities: scheduled_activities})
end
end
def show_scheduled_status(%{assigns: %{user: user}} = conn, %{"id" => scheduled_activity_id}) do
with %ScheduledActivity{} = scheduled_activity <-
ScheduledActivity.get(user, scheduled_activity_id) do
conn
|> put_view(ScheduledActivityView)
|> render("show.json", %{scheduled_activity: scheduled_activity})
else
_ -> {:error, :not_found}
end
end
def update_scheduled_status(
%{assigns: %{user: user}} = conn,
%{"id" => scheduled_activity_id} = params
) do
with %ScheduledActivity{} = scheduled_activity <-
ScheduledActivity.get(user, scheduled_activity_id),
{:ok, scheduled_activity} <- ScheduledActivity.update(scheduled_activity, params) do
conn
|> put_view(ScheduledActivityView)
|> render("show.json", %{scheduled_activity: scheduled_activity})
else
nil -> {:error, :not_found}
error -> error
end
end
def delete_scheduled_status(%{assigns: %{user: user}} = conn, %{"id" => scheduled_activity_id}) do
with %ScheduledActivity{} = scheduled_activity <-
ScheduledActivity.get(user, scheduled_activity_id),
{:ok, scheduled_activity} <- ScheduledActivity.delete(scheduled_activity) do
conn
|> put_view(ScheduledActivityView)
|> render("show.json", %{scheduled_activity: scheduled_activity})
else
nil -> {:error, :not_found}
error -> error
end
end
def post_status(conn, %{"status" => "", "media_ids" => media_ids} = params)
when length(media_ids) > 0 do
params =
@ -384,12 +436,27 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
_ -> Ecto.UUID.generate()
end
{:ok, activity} =
Cachex.fetch!(:idempotency_cache, idempotency_key, fn _ -> CommonAPI.post(user, params) end)
scheduled_at = params["scheduled_at"]
conn
|> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
if scheduled_at && ScheduledActivity.far_enough?(scheduled_at) do
with {:ok, scheduled_activity} <-
ScheduledActivity.create(user, %{"params" => params, "scheduled_at" => scheduled_at}) do
conn
|> put_view(ScheduledActivityView)
|> render("show.json", %{scheduled_activity: scheduled_activity})
end
else
params = Map.drop(params, ["scheduled_at"])
{:ok, activity} =
Cachex.fetch!(:idempotency_cache, idempotency_key, fn _ ->
CommonAPI.post(user, params)
end)
conn
|> put_view(StatusView)
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
end
end
def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
@ -1091,9 +1158,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def index(%{assigns: %{user: user}} = conn, _params) do
token =
conn
|> get_session(:oauth_token)
token = get_session(conn, :oauth_token)
if user && token do
mastodon_emoji = mastodonized_emoji()
@ -1121,7 +1186,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
auto_play_gif: false,
display_sensitive_media: false,
reduce_motion: false,
max_toot_chars: limit
max_toot_chars: limit,
mascot: "/images/pleroma-fox-tan-smol.png"
},
rights: %{
delete_others_notice: present?(user.info.is_moderator),
@ -1193,6 +1259,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|> render("index.html", %{initial_state: initial_state, flavour: flavour})
else
conn
|> put_session(:return_to, conn.request_path)
|> redirect(to: "/web/login")
end
end
@ -1277,12 +1344,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
scope: Enum.join(app.scopes, " ")
)
conn
|> redirect(to: path)
redirect(conn, to: path)
end
end
defp local_mastodon_root_path(conn), do: mastodon_api_path(conn, :index, ["getting-started"])
defp local_mastodon_root_path(conn) do
case get_session(conn, :return_to) do
nil ->
mastodon_api_path(conn, :index, ["getting-started"])
return_to ->
delete_session(conn, :return_to)
return_to
end
end
defp get_or_make_app do
find_attrs = %{client_name: @local_mastodon_name, redirect_uris: "."}
@ -1398,6 +1473,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
# fallback action
#
def errors(conn, {:error, %Changeset{} = changeset}) do
error_message =
changeset
|> Changeset.traverse_errors(fn {message, _opt} -> message end)
|> Enum.map_join(", ", fn {_k, v} -> v end)
conn
|> put_status(422)
|> json(%{error: error_message})
end
def errors(conn, {:error, :not_found}) do
conn
|> put_status(404)
|> json(%{error: "Record not found"})
end
def errors(conn, _) do
conn
|> put_status(500)

View file

@ -0,0 +1,57 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do
use Pleroma.Web, :view
alias Pleroma.ScheduledActivity
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
alias Pleroma.Web.MastodonAPI.StatusView
def render("index.json", %{scheduled_activities: scheduled_activities}) do
render_many(scheduled_activities, ScheduledActivityView, "show.json")
end
def render("show.json", %{scheduled_activity: %ScheduledActivity{} = scheduled_activity}) do
%{
id: to_string(scheduled_activity.id),
scheduled_at: CommonAPI.Utils.to_masto_date(scheduled_activity.scheduled_at),
params: status_params(scheduled_activity.params)
}
|> with_media_attachments(scheduled_activity)
end
defp with_media_attachments(data, %{params: %{"media_attachments" => media_attachments}}) do
try do
attachments = render_many(media_attachments, StatusView, "attachment.json", as: :attachment)
Map.put(data, :media_attachments, attachments)
rescue
_ -> data
end
end
defp with_media_attachments(data, _), do: data
defp status_params(params) do
data = %{
text: params["status"],
sensitive: params["sensitive"],
spoiler_text: params["spoiler_text"],
visibility: params["visibility"],
scheduled_at: params["scheduled_at"],
poll: params["poll"],
in_reply_to_id: params["in_reply_to_id"]
}
data =
if media_ids = params["media_ids"] do
Map.put(data, :media_ids, media_ids)
else
data
end
data
end
end

View file

@ -147,10 +147,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
content =
object
|> render_content()
|> HTML.get_cached_scrubbed_html_for_object(
|> HTML.get_cached_scrubbed_html_for_activity(
User.html_filter_policy(opts[:for]),
activity,
__MODULE__
"mastoapi:content"
)
summary =
(object["summary"] || "")
|> HTML.get_cached_scrubbed_html_for_activity(
User.html_filter_policy(opts[:for]),
activity,
"mastoapi:summary"
)
card = render("card.json", Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity))
@ -182,7 +190,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
muted: CommonAPI.thread_muted?(user, activity) || User.mutes?(opts[:for], user),
pinned: pinned?(activity, user),
sensitive: sensitive,
spoiler_text: object["summary"] || "",
spoiler_text: summary,
visibility: get_visibility(object),
media_attachments: attachments,
mentions: mentions,

View file

@ -12,7 +12,7 @@ defmodule Pleroma.Web.Metadata.Utils do
# html content comes from DB already encoded, decode first and scrub after
|> HtmlEntities.decode()
|> String.replace(~r/<br\s?\/?>/, " ")
|> HTML.get_cached_stripped_html_for_object(object, __MODULE__)
|> HTML.get_cached_stripped_html_for_activity(object, "metadata")
|> Formatter.demojify()
|> Formatter.truncate()
end

View file

@ -152,6 +152,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
with {_, {:ok, %User{} = user}} <- {:get_user, Authenticator.get_user(conn)},
%App{} = app <- get_app_from_request(conn, params),
{:auth_active, true} <- {:auth_active, User.auth_active?(user)},
{:user_active, true} <- {:user_active, !user.info.deactivated},
scopes <- oauth_scopes(params, app.scopes),
[] <- scopes -- app.scopes,
true <- Enum.any?(scopes),
@ -175,6 +176,11 @@ defmodule Pleroma.Web.OAuth.OAuthController do
|> put_status(:forbidden)
|> json(%{error: "Your login is missing a confirmed e-mail address"})
{:user_active, false} ->
conn
|> put_status(:forbidden)
|> json(%{error: "Your account is currently disabled"})
_error ->
put_status(conn, 400)
|> json(%{error: "Invalid credentials"})

View file

@ -140,8 +140,12 @@ defmodule Pleroma.Web.Router do
scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
pipe_through([:admin_api, :oauth_write])
post("/user/follow", AdminAPIController, :user_follow)
post("/user/unfollow", AdminAPIController, :user_unfollow)
get("/users", AdminAPIController, :list_users)
get("/users/:nickname", AdminAPIController, :user_show)
delete("/user", AdminAPIController, :user_delete)
patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation)
post("/user", AdminAPIController, :user_create)
@ -240,6 +244,9 @@ defmodule Pleroma.Web.Router do
get("/notifications", MastodonAPIController, :notifications)
get("/notifications/:id", MastodonAPIController, :get_notification)
get("/scheduled_statuses", MastodonAPIController, :scheduled_statuses)
get("/scheduled_statuses/:id", MastodonAPIController, :show_scheduled_status)
get("/lists", MastodonAPIController, :get_lists)
get("/lists/:id", MastodonAPIController, :get_list)
get("/lists/:id/accounts", MastodonAPIController, :list_accounts)
@ -274,6 +281,9 @@ defmodule Pleroma.Web.Router do
post("/statuses/:id/mute", MastodonAPIController, :mute_conversation)
post("/statuses/:id/unmute", MastodonAPIController, :unmute_conversation)
put("/scheduled_statuses/:id", MastodonAPIController, :update_scheduled_status)
delete("/scheduled_statuses/:id", MastodonAPIController, :delete_scheduled_status)
post("/media", MastodonAPIController, :upload)
put("/media/:id", MastodonAPIController, :update_media)

View file

@ -254,10 +254,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
html =
content
|> HTML.get_cached_scrubbed_html_for_object(
|> HTML.get_cached_scrubbed_html_for_activity(
User.html_filter_policy(opts[:for]),
activity,
__MODULE__
"twitterapi:content"
)
|> Formatter.emojify(object["emoji"])
@ -265,7 +265,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
if content do
content
|> String.replace(~r/<br\s?\/?>/, "\n")
|> HTML.get_cached_stripped_html_for_object(activity, __MODULE__)
|> HTML.get_cached_stripped_html_for_activity(activity, "twitterapi:content")
else
""
end