Merge branch 'split-masto-api/masto_fe_and_custom_emojis' into 'develop'

[#1278] Move actions from MastodonAPIController to CustomEmojiController and MastoFEController

See merge request pleroma/pleroma!1772
This commit is contained in:
rinpatch 2019-10-02 14:17:21 +00:00
commit c5e937b156
13 changed files with 295 additions and 255 deletions

View File

@ -0,0 +1,36 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastoFEController do
use Pleroma.Web, :controller
alias Pleroma.User
@doc "GET /web/*path"
def index(%{assigns: %{user: user}} = conn, _params) do
token = get_session(conn, :oauth_token)
if user && token do
conn
|> put_layout(false)
|> render("index.html", token: token, user: user, custom_emojis: Pleroma.Emoji.get_all())
else
conn
|> put_session(:return_to, conn.request_path)
|> redirect(to: "/web/login")
end
end
@doc "PUT /api/web/settings"
def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do
with {:ok, _} <- User.update_info(user, &User.Info.mastodon_settings_update(&1, settings)) do
json(conn, %{})
else
e ->
conn
|> put_status(:internal_server_error)
|> json(%{error: inspect(e)})
end
end
end

View File

@ -75,7 +75,7 @@ def password_reset(conn, params) do
defp local_mastodon_root_path(conn) do defp local_mastodon_root_path(conn) do
case get_session(conn, :return_to) do case get_session(conn, :return_to) do
nil -> nil ->
mastodon_api_path(conn, :index, ["getting-started"]) masto_fe_path(conn, :index, ["getting-started"])
return_to -> return_to ->
delete_session(conn, :return_to) delete_session(conn, :return_to)

View File

@ -0,0 +1,11 @@
# 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.CustomEmojiController do
use Pleroma.Web, :controller
def index(conn, _params) do
render(conn, "index.json", custom_emojis: Pleroma.Emoji.get_all())
end
end

View File

@ -8,42 +8,17 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2] import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Bookmark alias Pleroma.Bookmark
alias Pleroma.Config
alias Pleroma.Pagination alias Pleroma.Pagination
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.MastodonView
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
require Logger require Logger
action_fallback(Pleroma.Web.MastodonAPI.FallbackController) action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
defp mastodonized_emoji do
Pleroma.Emoji.get_all()
|> Enum.map(fn {shortcode, %Pleroma.Emoji{file: relative_url, tags: tags}} ->
url = to_string(URI.merge(Web.base_url(), relative_url))
%{
"shortcode" => shortcode,
"static_url" => url,
"visible_in_picker" => true,
"url" => url,
"tags" => tags,
# Assuming that a comma is authorized in the category name
"category" => (tags -- ["Custom"]) |> Enum.join(",")
}
end)
end
def custom_emojis(conn, _params) do
mastodon_emoji = mastodonized_emoji()
json(conn, mastodon_emoji)
end
def follows(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do def follows(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
with {_, %User{} = followed} <- {:followed, User.get_cached_by_nickname(uri)}, with {_, %User{} = followed} <- {:followed, User.get_cached_by_nickname(uri)},
{_, true} <- {:followed, follower.id != followed.id}, {_, true} <- {:followed, follower.id != followed.id},
@ -110,121 +85,6 @@ def bookmarks(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", %{activities: activities, for: user, as: :activity}) |> render("index.json", %{activities: activities, for: user, as: :activity})
end end
def index(%{assigns: %{user: user}} = conn, _params) do
token = get_session(conn, :oauth_token)
if user && token do
mastodon_emoji = mastodonized_emoji()
limit = Config.get([:instance, :limit])
accounts = Map.put(%{}, user.id, AccountView.render("show.json", %{user: user, for: user}))
initial_state =
%{
meta: %{
streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(),
access_token: token,
locale: "en",
domain: Pleroma.Web.Endpoint.host(),
admin: "1",
me: "#{user.id}",
unfollow_modal: false,
boost_modal: false,
delete_modal: true,
auto_play_gif: false,
display_sensitive_media: false,
reduce_motion: false,
max_toot_chars: limit,
mascot: User.get_mascot(user)["url"]
},
poll_limits: Config.get([:instance, :poll_limits]),
rights: %{
delete_others_notice: present?(user.info.is_moderator),
admin: present?(user.info.is_admin)
},
compose: %{
me: "#{user.id}",
default_privacy: user.info.default_scope,
default_sensitive: false,
allow_content_types: Config.get([:instance, :allowed_post_formats])
},
media_attachments: %{
accept_content_types: [
".jpg",
".jpeg",
".png",
".gif",
".webm",
".mp4",
".m4v",
"image\/jpeg",
"image\/png",
"image\/gif",
"video\/webm",
"video\/mp4"
]
},
settings:
user.info.settings ||
%{
onboarded: true,
home: %{
shows: %{
reblog: true,
reply: true
}
},
notifications: %{
alerts: %{
follow: true,
favourite: true,
reblog: true,
mention: true
},
shows: %{
follow: true,
favourite: true,
reblog: true,
mention: true
},
sounds: %{
follow: true,
favourite: true,
reblog: true,
mention: true
}
}
},
push_subscription: nil,
accounts: accounts,
custom_emojis: mastodon_emoji,
char_limit: limit
}
|> Jason.encode!()
conn
|> put_layout(false)
|> put_view(MastodonView)
|> render("index.html", %{initial_state: initial_state})
else
conn
|> put_session(:return_to, conn.request_path)
|> redirect(to: "/web/login")
end
end
def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do
with {:ok, _} <- User.update_info(user, &User.Info.mastodon_settings_update(&1, settings)) do
json(conn, %{})
else
e ->
conn
|> put_status(:internal_server_error)
|> json(%{error: inspect(e)})
end
end
# Stubs for unimplemented mastodon api # Stubs for unimplemented mastodon api
# #
def empty_array(conn, _) do def empty_array(conn, _) do
@ -236,8 +96,4 @@ def empty_object(conn, _) do
Logger.debug("Unimplemented, returning an empty object") Logger.debug("Unimplemented, returning an empty object")
json(conn, %{}) json(conn, %{})
end end
defp present?(nil), do: false
defp present?(false), do: false
defp present?(_), do: true
end end

View File

@ -0,0 +1,28 @@
# 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.CustomEmojiView do
use Pleroma.Web, :view
alias Pleroma.Emoji
alias Pleroma.Web
def render("index.json", %{custom_emojis: custom_emojis}) do
render_many(custom_emojis, __MODULE__, "show.json")
end
def render("show.json", %{custom_emoji: {shortcode, %Emoji{file: relative_url, tags: tags}}}) do
url = Web.base_url() |> URI.merge(relative_url) |> to_string()
%{
"shortcode" => shortcode,
"static_url" => url,
"visible_in_picker" => true,
"url" => url,
"tags" => tags,
# Assuming that a comma is authorized in the category name
"category" => tags |> List.delete("Custom") |> Enum.join(",")
}
end
end

View File

@ -1,8 +0,0 @@
# 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.MastodonView do
use Pleroma.Web, :view
import Phoenix.HTML
end

View File

@ -451,16 +451,17 @@ defmodule Pleroma.Web.Router do
end end
end end
scope "/api/web", Pleroma.Web.MastodonAPI do scope "/api/web", Pleroma.Web do
pipe_through([:authenticated_api, :oauth_write]) pipe_through([:authenticated_api, :oauth_write])
put("/settings", MastodonAPIController, :put_settings) put("/settings", MastoFEController, :put_settings)
end end
scope "/api/v1", Pleroma.Web.MastodonAPI do scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:api) pipe_through(:api)
post("/accounts", AccountController, :create) post("/accounts", AccountController, :create)
get("/accounts/search", SearchController, :account_search)
get("/instance", InstanceController, :show) get("/instance", InstanceController, :show)
get("/instance/peers", InstanceController, :peers) get("/instance/peers", InstanceController, :peers)
@ -468,15 +469,13 @@ defmodule Pleroma.Web.Router do
post("/apps", AppController, :create) post("/apps", AppController, :create)
get("/apps/verify_credentials", AppController, :verify_credentials) get("/apps/verify_credentials", AppController, :verify_credentials)
get("/custom_emojis", MastodonAPIController, :custom_emojis)
get("/statuses/:id/card", StatusController, :card) get("/statuses/:id/card", StatusController, :card)
get("/statuses/:id/favourited_by", StatusController, :favourited_by) get("/statuses/:id/favourited_by", StatusController, :favourited_by)
get("/statuses/:id/reblogged_by", StatusController, :reblogged_by) get("/statuses/:id/reblogged_by", StatusController, :reblogged_by)
get("/trends", MastodonAPIController, :empty_array) get("/custom_emojis", CustomEmojiController, :index)
get("/accounts/search", SearchController, :account_search) get("/trends", MastodonAPIController, :empty_array)
scope [] do scope [] do
pipe_through(:oauth_read_or_public) pipe_through(:oauth_read_or_public)
@ -659,17 +658,17 @@ defmodule Pleroma.Web.Router do
get("/:version", Nodeinfo.NodeinfoController, :nodeinfo) get("/:version", Nodeinfo.NodeinfoController, :nodeinfo)
end end
scope "/", Pleroma.Web.MastodonAPI do scope "/", Pleroma.Web do
pipe_through(:mastodon_html) pipe_through(:mastodon_html)
get("/web/login", AuthController, :login) get("/web/login", MastodonAPI.AuthController, :login)
delete("/auth/sign_out", AuthController, :logout) delete("/auth/sign_out", MastodonAPI.AuthController, :logout)
post("/auth/password", AuthController, :password_reset) post("/auth/password", MastodonAPI.AuthController, :password_reset)
scope [] do scope [] do
pipe_through(:oauth_read) pipe_through(:oauth_read)
get("/web/*path", MastodonAPIController, :index) get("/web/*path", MastoFEController, :index)
end end
end end

View File

@ -14,7 +14,7 @@
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/compose.js'> <link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/compose.js'>
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/home_timeline.js'> <link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/home_timeline.js'>
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/notifications.js'> <link rel='preload' as='script' crossorigin='anonymous' href='/packs/features/notifications.js'>
<script id='initial-state' type='application/json'><%= raw @initial_state %></script> <script id='initial-state' type='application/json'><%= initial_state(@token, @user, @custom_emojis) %></script>
<script src="/packs/core/common.js"></script> <script src="/packs/core/common.js"></script>
<link rel="stylesheet" media="all" href="/packs/core/common.css" /> <link rel="stylesheet" media="all" href="/packs/core/common.css" />

View File

@ -0,0 +1,102 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastoFEView do
use Pleroma.Web, :view
alias Pleroma.Config
alias Pleroma.User
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.CustomEmojiView
@default_settings %{
onboarded: true,
home: %{
shows: %{
reblog: true,
reply: true
}
},
notifications: %{
alerts: %{
follow: true,
favourite: true,
reblog: true,
mention: true
},
shows: %{
follow: true,
favourite: true,
reblog: true,
mention: true
},
sounds: %{
follow: true,
favourite: true,
reblog: true,
mention: true
}
}
}
def initial_state(token, user, custom_emojis) do
limit = Config.get([:instance, :limit])
%{
meta: %{
streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(),
access_token: token,
locale: "en",
domain: Pleroma.Web.Endpoint.host(),
admin: "1",
me: "#{user.id}",
unfollow_modal: false,
boost_modal: false,
delete_modal: true,
auto_play_gif: false,
display_sensitive_media: false,
reduce_motion: false,
max_toot_chars: limit,
mascot: User.get_mascot(user)["url"]
},
poll_limits: Config.get([:instance, :poll_limits]),
rights: %{
delete_others_notice: present?(user.info.is_moderator),
admin: present?(user.info.is_admin)
},
compose: %{
me: "#{user.id}",
default_privacy: user.info.default_scope,
default_sensitive: false,
allow_content_types: Config.get([:instance, :allowed_post_formats])
},
media_attachments: %{
accept_content_types: [
".jpg",
".jpeg",
".png",
".gif",
".webm",
".mp4",
".m4v",
"image\/jpeg",
"image\/png",
"image\/gif",
"video\/webm",
"video\/mp4"
]
},
settings: user.info.settings || @default_settings,
push_subscription: nil,
accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)},
custom_emojis: render(CustomEmojiView, "index.json", custom_emojis: custom_emojis),
char_limit: limit
}
|> Jason.encode!()
|> Phoenix.HTML.raw()
end
defp present?(nil), do: false
defp present?(false), do: false
defp present?(_), do: true
end

View File

@ -1084,7 +1084,6 @@ test "it inlines private announced objects" do
{:ok, announce_activity, _} = CommonAPI.repeat(activity.id, user) {:ok, announce_activity, _} = CommonAPI.repeat(activity.id, user)
{:ok, modified} = Transmogrifier.prepare_outgoing(announce_activity.data) {:ok, modified} = Transmogrifier.prepare_outgoing(announce_activity.data)
object = modified["object"]
assert modified["object"]["content"] == "hey" assert modified["object"]["content"] == "hey"
assert modified["object"]["actor"] == modified["object"]["attributedTo"] assert modified["object"]["actor"] == modified["object"]["attributedTo"]

View File

@ -0,0 +1,84 @@
# 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.MastoFEController do
use Pleroma.Web.ConnCase
alias Pleroma.Config
alias Pleroma.User
import Pleroma.Factory
clear_config([:instance, :public])
test "put settings", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
assert _result = json_response(conn, 200)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.info.settings == %{"programming" => "socks"}
end
describe "index/2 redirections" do
setup %{conn: conn} do
session_opts = [
store: :cookie,
key: "_test",
signing_salt: "cooldude"
]
conn =
conn
|> Plug.Session.call(Plug.Session.init(session_opts))
|> fetch_session()
test_path = "/web/statuses/test"
%{conn: conn, path: test_path}
end
test "redirects not logged-in users to the login page", %{conn: conn, path: path} do
conn = get(conn, path)
assert conn.status == 302
assert redirected_to(conn) == "/web/login"
end
test "redirects not logged-in users to the login page on private instances", %{
conn: conn,
path: path
} do
Config.put([:instance, :public], false)
conn = get(conn, path)
assert conn.status == 302
assert redirected_to(conn) == "/web/login"
end
test "does not redirect logged in users to the login page", %{conn: conn, path: path} do
token = insert(:oauth_token)
conn =
conn
|> assign(:user, token.user)
|> put_session(:oauth_token, token.token)
|> get(path)
assert conn.status == 200
end
test "saves referer path to session", %{conn: conn, path: path} do
conn = get(conn, path)
return_to = Plug.Conn.get_session(conn, :return_to)
assert return_to == path
end
end
end

View File

@ -0,0 +1,22 @@
# 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.CustomEmojiControllerTest do
use Pleroma.Web.ConnCase, async: true
test "with tags", %{conn: conn} do
[emoji | _body] =
conn
|> get("/api/v1/custom_emojis")
|> json_response(200)
assert Map.has_key?(emoji, "shortcode")
assert Map.has_key?(emoji, "static_url")
assert Map.has_key?(emoji, "tags")
assert is_list(emoji["tags"])
assert Map.has_key?(emoji, "category")
assert Map.has_key?(emoji, "url")
assert Map.has_key?(emoji, "visible_in_picker")
end
end

View File

@ -5,7 +5,6 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase
alias Pleroma.Config
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
@ -19,7 +18,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
:ok :ok
end end
clear_config([:instance, :public])
clear_config([:rich_media, :enabled]) clear_config([:rich_media, :enabled])
test "getting a list of mutes", %{conn: conn} do test "getting a list of mutes", %{conn: conn} do
@ -113,20 +111,6 @@ test "returns the favorites of a user", %{conn: conn} do
assert [] = json_response(third_conn, 200) assert [] = json_response(third_conn, 200)
end end
test "put settings", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
assert _result = json_response(conn, 200)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.info.settings == %{"programming" => "socks"}
end
describe "link headers" do describe "link headers" do
test "preserves parameters in link headers", %{conn: conn} do test "preserves parameters in link headers", %{conn: conn} do
user = insert(:user) user = insert(:user)
@ -159,79 +143,6 @@ test "preserves parameters in link headers", %{conn: conn} do
end end
end end
describe "custom emoji" do
test "with tags", %{conn: conn} do
[emoji | _body] =
conn
|> get("/api/v1/custom_emojis")
|> json_response(200)
assert Map.has_key?(emoji, "shortcode")
assert Map.has_key?(emoji, "static_url")
assert Map.has_key?(emoji, "tags")
assert is_list(emoji["tags"])
assert Map.has_key?(emoji, "category")
assert Map.has_key?(emoji, "url")
assert Map.has_key?(emoji, "visible_in_picker")
end
end
describe "index/2 redirections" do
setup %{conn: conn} do
session_opts = [
store: :cookie,
key: "_test",
signing_salt: "cooldude"
]
conn =
conn
|> Plug.Session.call(Plug.Session.init(session_opts))
|> fetch_session()
test_path = "/web/statuses/test"
%{conn: conn, path: test_path}
end
test "redirects not logged-in users to the login page", %{conn: conn, path: path} do
conn = get(conn, path)
assert conn.status == 302
assert redirected_to(conn) == "/web/login"
end
test "redirects not logged-in users to the login page on private instances", %{
conn: conn,
path: path
} do
Config.put([:instance, :public], false)
conn = get(conn, path)
assert conn.status == 302
assert redirected_to(conn) == "/web/login"
end
test "does not redirect logged in users to the login page", %{conn: conn, path: path} do
token = insert(:oauth_token)
conn =
conn
|> assign(:user, token.user)
|> put_session(:oauth_token, token.token)
|> get(path)
assert conn.status == 200
end
test "saves referer path to session", %{conn: conn, path: path} do
conn = get(conn, path)
return_to = Plug.Conn.get_session(conn, :return_to)
assert return_to == path
end
end
describe "empty_array, stubs for mastodon api" do describe "empty_array, stubs for mastodon api" do
test "GET /api/v1/accounts/:id/identity_proofs", %{conn: conn} do test "GET /api/v1/accounts/:id/identity_proofs", %{conn: conn} do
user = insert(:user) user = insert(:user)