Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85829755
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
48 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex
new file mode 100644
index 000000000..a55f60fec
--- /dev/null
+++ b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex
@@ -0,0 +1,17 @@
+# 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.InstanceController do
+ use Pleroma.Web, :controller
+
+ @doc "GET /api/v1/instance"
+ def show(conn, _params) do
+ render(conn, "show.json")
+ end
+
+ @doc "GET /api/v1/instance/peers"
+ def peers(conn, _params) do
+ json(conn, Pleroma.Stats.get_peers())
+ end
+end
diff --git a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
index 81a95bc4a..98dd9f375 100644
--- a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
@@ -1,278 +1,243 @@
# 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.MastodonAPIController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Bookmark
alias Pleroma.Config
alias Pleroma.Pagination
- alias Pleroma.Stats
alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.MastodonView
alias Pleroma.Web.MastodonAPI.StatusView
require Logger
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
- @mastodon_api_level "2.7.2"
-
- def masto_instance(conn, _params) do
- instance = Config.get(:instance)
-
- response = %{
- uri: Web.base_url(),
- title: Keyword.get(instance, :name),
- description: Keyword.get(instance, :description),
- version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})",
- email: Keyword.get(instance, :email),
- urls: %{
- streaming_api: Pleroma.Web.Endpoint.websocket_url()
- },
- stats: Stats.get_stats(),
- thumbnail: Web.base_url() <> "/instance/thumbnail.jpeg",
- languages: ["en"],
- registrations: Pleroma.Config.get([:instance, :registrations_open]),
- # Extra (not present in Mastodon):
- max_toot_chars: Keyword.get(instance, :limit),
- poll_limits: Keyword.get(instance, :poll_limits),
- upload_limit: Keyword.get(instance, :upload_limit),
- avatar_upload_limit: Keyword.get(instance, :avatar_upload_limit),
- background_upload_limit: Keyword.get(instance, :background_upload_limit),
- banner_upload_limit: Keyword.get(instance, :banner_upload_limit)
- }
-
- json(conn, response)
- end
-
- def peers(conn, _params) do
- json(conn, Stats.get_peers())
- end
-
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
with {_, %User{} = followed} <- {:followed, User.get_cached_by_nickname(uri)},
{_, true} <- {:followed, follower.id != followed.id},
{:ok, follower, followed, _} <- CommonAPI.follow(follower, followed) do
conn
|> put_view(AccountView)
|> render("show.json", %{user: followed, for: follower})
else
{:followed, _} ->
{:error, :not_found}
{:error, message} ->
conn
|> put_status(:forbidden)
|> json(%{error: message})
end
end
def mutes(%{assigns: %{user: user}} = conn, _) do
with muted_accounts <- User.muted_users(user) do
res = AccountView.render("index.json", users: muted_accounts, for: user, as: :user)
json(conn, res)
end
end
def blocks(%{assigns: %{user: user}} = conn, _) do
with blocked_accounts <- User.blocked_users(user) do
res = AccountView.render("index.json", users: blocked_accounts, for: user, as: :user)
json(conn, res)
end
end
def favourites(%{assigns: %{user: user}} = conn, params) do
params =
params
|> Map.put("type", "Create")
|> Map.put("favorited_by", user.ap_id)
|> Map.put("blocking_user", user)
activities =
ActivityPub.fetch_activities([], params)
|> Enum.reverse()
conn
|> add_link_headers(activities)
|> put_view(StatusView)
|> render("index.json", %{activities: activities, for: user, as: :activity})
end
def bookmarks(%{assigns: %{user: user}} = conn, params) do
user = User.get_cached_by_id(user.id)
bookmarks =
Bookmark.for_user_query(user.id)
|> Pagination.fetch_paginated(params)
activities =
bookmarks
|> Enum.map(fn b -> Map.put(b.activity, :bookmark, Map.delete(b, :activity)) end)
conn
|> add_link_headers(bookmarks)
|> put_view(StatusView)
|> render("index.json", %{activities: activities, for: user, as: :activity})
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
#
def empty_array(conn, _) do
Logger.debug("Unimplemented, returning an empty array")
json(conn, [])
end
def empty_object(conn, _) do
Logger.debug("Unimplemented, returning an empty object")
json(conn, %{})
end
defp present?(nil), do: false
defp present?(false), do: false
defp present?(_), do: true
end
diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex
new file mode 100644
index 000000000..c4866e510
--- /dev/null
+++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex
@@ -0,0 +1,35 @@
+# 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.InstanceView do
+ use Pleroma.Web, :view
+
+ @mastodon_api_level "2.7.2"
+
+ def render("show.json", _) do
+ instance = Pleroma.Config.get(:instance)
+
+ %{
+ uri: Pleroma.Web.base_url(),
+ title: Keyword.get(instance, :name),
+ description: Keyword.get(instance, :description),
+ version: "#{@mastodon_api_level} (compatible; #{Pleroma.Application.named_version()})",
+ email: Keyword.get(instance, :email),
+ urls: %{
+ streaming_api: Pleroma.Web.Endpoint.websocket_url()
+ },
+ stats: Pleroma.Stats.get_stats(),
+ thumbnail: Pleroma.Web.base_url() <> "/instance/thumbnail.jpeg",
+ languages: ["en"],
+ registrations: Keyword.get(instance, :registrations_open),
+ # Extra (not present in Mastodon):
+ max_toot_chars: Keyword.get(instance, :limit),
+ poll_limits: Keyword.get(instance, :poll_limits),
+ upload_limit: Keyword.get(instance, :upload_limit),
+ avatar_upload_limit: Keyword.get(instance, :avatar_upload_limit),
+ background_upload_limit: Keyword.get(instance, :background_upload_limit),
+ banner_upload_limit: Keyword.get(instance, :banner_upload_limit)
+ }
+ end
+end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 501978994..a355a14bd 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -1,706 +1,707 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Router do
use Pleroma.Web, :router
pipeline :browser do
plug(:accepts, ["html"])
plug(:fetch_session)
end
pipeline :oauth do
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
end
pipeline :api do
plug(:accepts, ["json"])
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug)
plug(Pleroma.Plugs.IdempotencyPlug)
end
pipeline :authenticated_api do
plug(:accepts, ["json"])
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureAuthenticatedPlug)
plug(Pleroma.Plugs.IdempotencyPlug)
end
pipeline :admin_api do
plug(:accepts, ["json"])
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.AdminSecretAuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureAuthenticatedPlug)
plug(Pleroma.Plugs.UserIsAdminPlug)
plug(Pleroma.Plugs.IdempotencyPlug)
end
pipeline :mastodon_html do
plug(:accepts, ["html"])
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug)
end
pipeline :pleroma_html do
plug(:accepts, ["html"])
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug)
end
pipeline :oauth_read_or_public do
plug(Pleroma.Plugs.OAuthScopesPlug, %{
scopes: ["read"],
fallback: :proceed_unauthenticated
})
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
end
pipeline :oauth_read do
plug(Pleroma.Plugs.OAuthScopesPlug, %{scopes: ["read"]})
end
pipeline :oauth_write do
plug(Pleroma.Plugs.OAuthScopesPlug, %{scopes: ["write"]})
end
pipeline :oauth_follow do
plug(Pleroma.Plugs.OAuthScopesPlug, %{scopes: ["follow"]})
end
pipeline :oauth_push do
plug(Pleroma.Plugs.OAuthScopesPlug, %{scopes: ["push"]})
end
pipeline :well_known do
plug(:accepts, ["json", "jrd+json", "xml", "xrd+xml"])
end
pipeline :config do
plug(:accepts, ["json", "xml"])
end
pipeline :pleroma_api do
plug(:accepts, ["html", "json"])
end
pipeline :mailbox_preview do
plug(:accepts, ["html"])
plug(:put_secure_browser_headers, %{
"content-security-policy" =>
"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' 'unsafe-eval'"
})
end
pipeline :http_signature do
plug(Pleroma.Web.Plugs.HTTPSignaturePlug)
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
pipe_through(:pleroma_api)
get("/password_reset/:token", PasswordController, :reset, as: :reset_password)
post("/password_reset", PasswordController, :do_reset, as: :reset_password)
get("/emoji", UtilController, :emoji)
get("/captcha", UtilController, :captcha)
get("/healthcheck", UtilController, :healthcheck)
end
scope "/api/pleroma", Pleroma.Web do
pipe_through(:pleroma_api)
post("/uploader_callback/:upload_path", UploaderController, :callback)
end
scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do
pipe_through([:admin_api, :oauth_write])
post("/users/follow", AdminAPIController, :user_follow)
post("/users/unfollow", AdminAPIController, :user_unfollow)
delete("/users", AdminAPIController, :user_delete)
post("/users", AdminAPIController, :users_create)
patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation)
put("/users/tag", AdminAPIController, :tag_users)
delete("/users/tag", AdminAPIController, :untag_users)
get("/users/:nickname/permission_group", AdminAPIController, :right_get)
get("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_get)
post("/users/:nickname/permission_group/:permission_group", AdminAPIController, :right_add)
delete(
"/users/:nickname/permission_group/:permission_group",
AdminAPIController,
:right_delete
)
put("/users/:nickname/activation_status", AdminAPIController, :set_activation_status)
post("/relay", AdminAPIController, :relay_follow)
delete("/relay", AdminAPIController, :relay_unfollow)
post("/users/invite_token", AdminAPIController, :create_invite_token)
get("/users/invites", AdminAPIController, :invites)
post("/users/revoke_invite", AdminAPIController, :revoke_invite)
post("/users/email_invite", AdminAPIController, :email_invite)
get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset)
patch("/users/:nickname/force_password_reset", AdminAPIController, :force_password_reset)
get("/users", AdminAPIController, :list_users)
get("/users/:nickname", AdminAPIController, :user_show)
get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses)
get("/reports", AdminAPIController, :list_reports)
get("/reports/:id", AdminAPIController, :report_show)
put("/reports/:id", AdminAPIController, :report_update_state)
post("/reports/:id/respond", AdminAPIController, :report_respond)
put("/statuses/:id", AdminAPIController, :status_update)
delete("/statuses/:id", AdminAPIController, :status_delete)
get("/config", AdminAPIController, :config_show)
post("/config", AdminAPIController, :config_update)
get("/config/migrate_to_db", AdminAPIController, :migrate_to_db)
get("/config/migrate_from_db", AdminAPIController, :migrate_from_db)
get("/moderation_log", AdminAPIController, :list_log)
post("/reload_emoji", AdminAPIController, :reload_emoji)
end
scope "/api/pleroma/emoji", Pleroma.Web.PleromaAPI do
scope "/packs" do
# Modifying packs
pipe_through([:admin_api, :oauth_write])
post("/import_from_fs", EmojiAPIController, :import_from_fs)
post("/:pack_name/update_file", EmojiAPIController, :update_file)
post("/:pack_name/update_metadata", EmojiAPIController, :update_metadata)
put("/:name", EmojiAPIController, :create)
delete("/:name", EmojiAPIController, :delete)
post("/download_from", EmojiAPIController, :download_from)
post("/list_from", EmojiAPIController, :list_from)
end
scope "/packs" do
# Pack info / downloading
get("/", EmojiAPIController, :list_packs)
get("/:name/download_shared/", EmojiAPIController, :download_shared)
end
end
scope "/", Pleroma.Web.TwitterAPI do
pipe_through(:pleroma_html)
post("/main/ostatus", UtilController, :remote_subscribe)
get("/ostatus_subscribe", UtilController, :remote_follow)
scope [] do
pipe_through(:oauth_follow)
post("/ostatus_subscribe", UtilController, :do_remote_follow)
end
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
pipe_through(:authenticated_api)
scope [] do
pipe_through(:oauth_write)
post("/change_email", UtilController, :change_email)
post("/change_password", UtilController, :change_password)
post("/delete_account", UtilController, :delete_account)
put("/notification_settings", UtilController, :update_notificaton_settings)
post("/disable_account", UtilController, :disable_account)
end
scope [] do
pipe_through(:oauth_follow)
post("/blocks_import", UtilController, :blocks_import)
post("/follow_import", UtilController, :follow_import)
end
end
scope "/oauth", Pleroma.Web.OAuth do
scope [] do
pipe_through(:oauth)
get("/authorize", OAuthController, :authorize)
end
post("/authorize", OAuthController, :create_authorization)
post("/token", OAuthController, :token_exchange)
post("/revoke", OAuthController, :token_revoke)
get("/registration_details", OAuthController, :registration_details)
scope [] do
pipe_through(:browser)
get("/prepare_request", OAuthController, :prepare_request)
get("/:provider", OAuthController, :request)
get("/:provider/callback", OAuthController, :callback)
post("/register", OAuthController, :register)
end
end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
scope [] do
pipe_through(:authenticated_api)
pipe_through(:oauth_read)
get("/conversations/:id/statuses", PleromaAPIController, :conversation_statuses)
get("/conversations/:id", PleromaAPIController, :conversation)
end
scope [] do
pipe_through(:authenticated_api)
pipe_through(:oauth_write)
patch("/conversations/:id", PleromaAPIController, :update_conversation)
post("/notifications/read", PleromaAPIController, :read_notification)
patch("/accounts/update_avatar", AccountController, :update_avatar)
patch("/accounts/update_banner", AccountController, :update_banner)
patch("/accounts/update_background", AccountController, :update_background)
get("/mascot", MascotController, :show)
put("/mascot", MascotController, :update)
post("/scrobble", ScrobbleController, :new_scrobble)
end
scope [] do
pipe_through(:api)
pipe_through(:oauth_read_or_public)
get("/accounts/:id/favourites", AccountController, :favourites)
end
scope [] do
pipe_through(:authenticated_api)
pipe_through(:oauth_follow)
post("/accounts/:id/subscribe", AccountController, :subscribe)
post("/accounts/:id/unsubscribe", AccountController, :unsubscribe)
end
post("/accounts/confirmation_resend", AccountController, :confirmation_resend)
end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
pipe_through([:api, :oauth_read_or_public])
get("/accounts/:id/scrobbles", ScrobbleController, :user_scrobbles)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:authenticated_api)
scope [] do
pipe_through(:oauth_read)
get("/accounts/verify_credentials", AccountController, :verify_credentials)
get("/accounts/relationships", AccountController, :relationships)
get("/accounts/:id/lists", AccountController, :lists)
get("/accounts/:id/identity_proofs", MastodonAPIController, :empty_array)
get("/follow_requests", FollowRequestController, :index)
get("/blocks", MastodonAPIController, :blocks)
get("/mutes", MastodonAPIController, :mutes)
get("/timelines/home", TimelineController, :home)
get("/timelines/direct", TimelineController, :direct)
get("/favourites", MastodonAPIController, :favourites)
get("/bookmarks", MastodonAPIController, :bookmarks)
get("/notifications", NotificationController, :index)
get("/notifications/:id", NotificationController, :show)
post("/notifications/clear", NotificationController, :clear)
post("/notifications/dismiss", NotificationController, :dismiss)
delete("/notifications/destroy_multiple", NotificationController, :destroy_multiple)
get("/scheduled_statuses", ScheduledActivityController, :index)
get("/scheduled_statuses/:id", ScheduledActivityController, :show)
get("/lists", ListController, :index)
get("/lists/:id", ListController, :show)
get("/lists/:id/accounts", ListController, :list_accounts)
get("/domain_blocks", DomainBlockController, :index)
get("/filters", FilterController, :index)
get("/suggestions", SuggestionController, :index)
get("/conversations", ConversationController, :index)
post("/conversations/:id/read", ConversationController, :read)
get("/endorsements", MastodonAPIController, :empty_array)
end
scope [] do
pipe_through(:oauth_write)
patch("/accounts/update_credentials", AccountController, :update_credentials)
post("/statuses", StatusController, :create)
delete("/statuses/:id", StatusController, :delete)
post("/statuses/:id/reblog", StatusController, :reblog)
post("/statuses/:id/unreblog", StatusController, :unreblog)
post("/statuses/:id/favourite", StatusController, :favourite)
post("/statuses/:id/unfavourite", StatusController, :unfavourite)
post("/statuses/:id/pin", StatusController, :pin)
post("/statuses/:id/unpin", StatusController, :unpin)
post("/statuses/:id/bookmark", StatusController, :bookmark)
post("/statuses/:id/unbookmark", StatusController, :unbookmark)
post("/statuses/:id/mute", StatusController, :mute_conversation)
post("/statuses/:id/unmute", StatusController, :unmute_conversation)
put("/scheduled_statuses/:id", ScheduledActivityController, :update)
delete("/scheduled_statuses/:id", ScheduledActivityController, :delete)
post("/polls/:id/votes", PollController, :vote)
post("/media", MediaController, :create)
put("/media/:id", MediaController, :update)
delete("/lists/:id", ListController, :delete)
post("/lists", ListController, :create)
put("/lists/:id", ListController, :update)
post("/lists/:id/accounts", ListController, :add_to_list)
delete("/lists/:id/accounts", ListController, :remove_from_list)
post("/filters", FilterController, :create)
get("/filters/:id", FilterController, :show)
put("/filters/:id", FilterController, :update)
delete("/filters/:id", FilterController, :delete)
post("/reports", ReportController, :create)
end
scope [] do
pipe_through(:oauth_follow)
post("/follows", MastodonAPIController, :follows)
post("/accounts/:id/follow", AccountController, :follow)
post("/accounts/:id/unfollow", AccountController, :unfollow)
post("/accounts/:id/block", AccountController, :block)
post("/accounts/:id/unblock", AccountController, :unblock)
post("/accounts/:id/mute", AccountController, :mute)
post("/accounts/:id/unmute", AccountController, :unmute)
post("/follow_requests/:id/authorize", FollowRequestController, :authorize)
post("/follow_requests/:id/reject", FollowRequestController, :reject)
post("/domain_blocks", DomainBlockController, :create)
delete("/domain_blocks", DomainBlockController, :delete)
end
scope [] do
pipe_through(:oauth_push)
post("/push/subscription", SubscriptionController, :create)
get("/push/subscription", SubscriptionController, :get)
put("/push/subscription", SubscriptionController, :update)
delete("/push/subscription", SubscriptionController, :delete)
end
end
scope "/api/web", Pleroma.Web.MastodonAPI do
pipe_through([:authenticated_api, :oauth_write])
put("/settings", MastodonAPIController, :put_settings)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:api)
post("/accounts", AccountController, :create)
- get("/instance", MastodonAPIController, :masto_instance)
- get("/instance/peers", MastodonAPIController, :peers)
+ get("/instance", InstanceController, :show)
+ get("/instance/peers", InstanceController, :peers)
+
post("/apps", AppController, :create)
get("/apps/verify_credentials", AppController, :verify_credentials)
+
get("/custom_emojis", MastodonAPIController, :custom_emojis)
get("/statuses/:id/card", StatusController, :card)
-
get("/statuses/:id/favourited_by", StatusController, :favourited_by)
get("/statuses/:id/reblogged_by", StatusController, :reblogged_by)
get("/trends", MastodonAPIController, :empty_array)
get("/accounts/search", SearchController, :account_search)
scope [] do
pipe_through(:oauth_read_or_public)
get("/timelines/public", TimelineController, :public)
get("/timelines/tag/:tag", TimelineController, :hashtag)
get("/timelines/list/:list_id", TimelineController, :list)
get("/statuses", StatusController, :index)
get("/statuses/:id", StatusController, :show)
get("/statuses/:id/context", StatusController, :context)
get("/polls/:id", PollController, :show)
get("/accounts/:id/statuses", AccountController, :statuses)
get("/accounts/:id/followers", AccountController, :followers)
get("/accounts/:id/following", AccountController, :following)
get("/accounts/:id", AccountController, :show)
get("/search", SearchController, :search)
end
end
scope "/api/v2", Pleroma.Web.MastodonAPI do
pipe_through([:api, :oauth_read_or_public])
get("/search", SearchController, :search2)
end
scope "/api", Pleroma.Web do
pipe_through(:config)
get("/help/test", TwitterAPI.UtilController, :help_test)
post("/help/test", TwitterAPI.UtilController, :help_test)
get("/statusnet/config", TwitterAPI.UtilController, :config)
get("/statusnet/version", TwitterAPI.UtilController, :version)
get("/pleroma/frontend_configurations", TwitterAPI.UtilController, :frontend_configurations)
end
scope "/api", Pleroma.Web do
pipe_through(:api)
get(
"/account/confirm_email/:user_id/:token",
TwitterAPI.Controller,
:confirm_email,
as: :confirm_email
)
end
scope "/api", Pleroma.Web, as: :authenticated_twitter_api do
pipe_through(:authenticated_api)
get("/oauth_tokens", TwitterAPI.Controller, :oauth_tokens)
delete("/oauth_tokens/:id", TwitterAPI.Controller, :revoke_token)
scope [] do
pipe_through(:oauth_read)
post("/qvitter/statuses/notifications/read", TwitterAPI.Controller, :notifications_read)
end
end
pipeline :ap_service_actor do
plug(:accepts, ["activity+json", "json"])
end
pipeline :ostatus do
plug(:accepts, ["html", "xml", "atom", "activity+json", "json"])
end
pipeline :oembed do
plug(:accepts, ["json", "xml"])
end
scope "/", Pleroma.Web do
pipe_through(:ostatus)
pipe_through(:http_signature)
get("/objects/:uuid", OStatus.OStatusController, :object)
get("/activities/:uuid", OStatus.OStatusController, :activity)
get("/notice/:id", OStatus.OStatusController, :notice)
get("/notice/:id/embed_player", OStatus.OStatusController, :notice_player)
get("/users/:nickname/feed", OStatus.OStatusController, :feed)
get("/users/:nickname", OStatus.OStatusController, :feed_redirect)
post("/users/:nickname/salmon", OStatus.OStatusController, :salmon_incoming)
post("/push/hub/:nickname", Websub.WebsubController, :websub_subscription_request)
get("/push/subscriptions/:id", Websub.WebsubController, :websub_subscription_confirmation)
post("/push/subscriptions/:id", Websub.WebsubController, :websub_incoming)
get("/mailer/unsubscribe/:token", Mailer.SubscriptionController, :unsubscribe)
end
pipeline :activitypub do
plug(:accepts, ["activity+json", "json"])
plug(Pleroma.Web.Plugs.HTTPSignaturePlug)
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
end
scope "/", Pleroma.Web.ActivityPub do
# XXX: not really ostatus
pipe_through(:ostatus)
get("/users/:nickname/outbox", ActivityPubController, :outbox)
get("/objects/:uuid/likes", ActivityPubController, :object_likes)
end
pipeline :activitypub_client do
plug(:accepts, ["activity+json", "json"])
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
plug(Pleroma.Plugs.BasicAuthDecoderPlug)
plug(Pleroma.Plugs.UserFetcherPlug)
plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureUserKeyPlug)
end
scope "/", Pleroma.Web.ActivityPub do
pipe_through([:activitypub_client])
scope [] do
pipe_through(:oauth_read)
get("/api/ap/whoami", ActivityPubController, :whoami)
get("/users/:nickname/inbox", ActivityPubController, :read_inbox)
end
scope [] do
pipe_through(:oauth_write)
post("/users/:nickname/outbox", ActivityPubController, :update_outbox)
post("/api/ap/upload_media", ActivityPubController, :upload_media)
end
scope [] do
pipe_through(:oauth_read_or_public)
get("/users/:nickname/followers", ActivityPubController, :followers)
get("/users/:nickname/following", ActivityPubController, :following)
end
end
scope "/", Pleroma.Web.ActivityPub do
pipe_through(:activitypub)
post("/inbox", ActivityPubController, :inbox)
post("/users/:nickname/inbox", ActivityPubController, :inbox)
end
scope "/relay", Pleroma.Web.ActivityPub do
pipe_through(:ap_service_actor)
get("/", ActivityPubController, :relay)
scope [] do
pipe_through(:http_signature)
post("/inbox", ActivityPubController, :inbox)
end
get("/following", ActivityPubController, :following, assigns: %{relay: true})
get("/followers", ActivityPubController, :followers, assigns: %{relay: true})
end
scope "/internal/fetch", Pleroma.Web.ActivityPub do
pipe_through(:ap_service_actor)
get("/", ActivityPubController, :internal_fetch)
post("/inbox", ActivityPubController, :inbox)
end
scope "/.well-known", Pleroma.Web do
pipe_through(:well_known)
get("/host-meta", WebFinger.WebFingerController, :host_meta)
get("/webfinger", WebFinger.WebFingerController, :webfinger)
get("/nodeinfo", Nodeinfo.NodeinfoController, :schemas)
end
scope "/nodeinfo", Pleroma.Web do
get("/:version", Nodeinfo.NodeinfoController, :nodeinfo)
end
scope "/", Pleroma.Web.MastodonAPI do
pipe_through(:mastodon_html)
get("/web/login", AuthController, :login)
delete("/auth/sign_out", AuthController, :logout)
post("/auth/password", AuthController, :password_reset)
scope [] do
pipe_through(:oauth_read)
get("/web/*path", MastodonAPIController, :index)
end
end
pipeline :remote_media do
end
scope "/proxy/", Pleroma.Web.MediaProxy do
pipe_through(:remote_media)
get("/:sig/:url", MediaProxyController, :remote)
get("/:sig/:url/:filename", MediaProxyController, :remote)
end
if Pleroma.Config.get(:env) == :dev do
scope "/dev" do
pipe_through([:mailbox_preview])
forward("/mailbox", Plug.Swoosh.MailboxPreview, base_path: "/dev/mailbox")
end
end
scope "/", Pleroma.Web.MongooseIM do
get("/user_exists", MongooseIMController, :user_exists)
get("/check_password", MongooseIMController, :check_password)
end
scope "/", Fallback do
get("/registration/:token", RedirectController, :registration_page)
get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
get("/api*path", RedirectController, :api_not_implemented)
get("/*path", RedirectController, :redirector)
options("/*path", RedirectController, :empty)
end
end
diff --git a/test/web/mastodon_api/controllers/instance_controller_test.exs b/test/web/mastodon_api/controllers/instance_controller_test.exs
new file mode 100644
index 000000000..f8049f81f
--- /dev/null
+++ b/test/web/mastodon_api/controllers/instance_controller_test.exs
@@ -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.InstanceControllerTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.User
+ import Pleroma.Factory
+
+ test "get instance information", %{conn: conn} do
+ conn = get(conn, "/api/v1/instance")
+ assert result = json_response(conn, 200)
+
+ email = Pleroma.Config.get([:instance, :email])
+ # Note: not checking for "max_toot_chars" since it's optional
+ assert %{
+ "uri" => _,
+ "title" => _,
+ "description" => _,
+ "version" => _,
+ "email" => from_config_email,
+ "urls" => %{
+ "streaming_api" => _
+ },
+ "stats" => _,
+ "thumbnail" => _,
+ "languages" => _,
+ "registrations" => _,
+ "poll_limits" => _,
+ "upload_limit" => _,
+ "avatar_upload_limit" => _,
+ "background_upload_limit" => _,
+ "banner_upload_limit" => _
+ } = result
+
+ assert email == from_config_email
+ end
+
+ test "get instance stats", %{conn: conn} do
+ user = insert(:user, %{local: true})
+
+ user2 = insert(:user, %{local: true})
+ {:ok, _user2} = User.deactivate(user2, !user2.info.deactivated)
+
+ insert(:user, %{local: false, nickname: "u@peer1.com"})
+ insert(:user, %{local: false, nickname: "u@peer2.com"})
+
+ {:ok, _} = Pleroma.Web.CommonAPI.post(user, %{"status" => "cofe"})
+
+ # Stats should count users with missing or nil `info.deactivated` value
+
+ {:ok, _user} =
+ user.id
+ |> User.get_cached_by_id()
+ |> User.update_info(&Ecto.Changeset.change(&1, %{deactivated: nil}))
+
+ Pleroma.Stats.force_update()
+
+ conn = get(conn, "/api/v1/instance")
+
+ assert result = json_response(conn, 200)
+
+ stats = result["stats"]
+
+ assert stats
+ assert stats["user_count"] == 1
+ assert stats["status_count"] == 1
+ assert stats["domain_count"] == 2
+ end
+
+ test "get peers", %{conn: conn} do
+ insert(:user, %{local: false, nickname: "u@peer1.com"})
+ insert(:user, %{local: false, nickname: "u@peer2.com"})
+
+ Pleroma.Stats.force_update()
+
+ conn = get(conn, "/api/v1/instance/peers")
+
+ assert result = json_response(conn, 200)
+
+ assert ["peer1.com", "peer2.com"] == Enum.sort(result)
+ end
+end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index e642e3c1a..7a58b13dc 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -1,347 +1,272 @@
# 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.MastodonAPIControllerTest do
use Pleroma.Web.ConnCase
- alias Ecto.Changeset
alias Pleroma.Config
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
import Tesla.Mock
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
clear_config([:instance, :public])
clear_config([:rich_media, :enabled])
test "getting a list of mutes", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.mute(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/mutes")
other_user_id = to_string(other_user.id)
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
test "getting a list of blocks", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.block(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/blocks")
other_user_id = to_string(other_user.id)
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
test "unimplemented follow_requests, blocks, domain blocks" do
user = insert(:user)
["blocks", "domain_blocks", "follow_requests"]
|> Enum.each(fn endpoint ->
conn =
build_conn()
|> assign(:user, user)
|> get("/api/v1/#{endpoint}")
assert [] = json_response(conn, 200)
end)
end
test "returns the favorites of a user", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{"status" => "bla"})
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "traps are happy"})
{:ok, _, _} = CommonAPI.favorite(activity.id, user)
first_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites")
assert [status] = json_response(first_conn, 200)
assert status["id"] == to_string(activity.id)
assert [{"link", _link_header}] =
Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end)
# Honours query params
{:ok, second_activity} =
CommonAPI.post(other_user, %{
"status" =>
"Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful."
})
{:ok, _, _} = CommonAPI.favorite(second_activity.id, user)
last_like = status["id"]
second_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites?since_id=#{last_like}")
assert [second_status] = json_response(second_conn, 200)
assert second_status["id"] == to_string(second_activity.id)
third_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites?limit=0")
assert [] = json_response(third_conn, 200)
end
- test "get instance information", %{conn: conn} do
- conn = get(conn, "/api/v1/instance")
- assert result = json_response(conn, 200)
-
- email = Config.get([:instance, :email])
- # Note: not checking for "max_toot_chars" since it's optional
- assert %{
- "uri" => _,
- "title" => _,
- "description" => _,
- "version" => _,
- "email" => from_config_email,
- "urls" => %{
- "streaming_api" => _
- },
- "stats" => _,
- "thumbnail" => _,
- "languages" => _,
- "registrations" => _,
- "poll_limits" => _,
- "upload_limit" => _,
- "avatar_upload_limit" => _,
- "background_upload_limit" => _,
- "banner_upload_limit" => _
- } = result
-
- assert email == from_config_email
- end
-
- test "get instance stats", %{conn: conn} do
- user = insert(:user, %{local: true})
-
- user2 = insert(:user, %{local: true})
- {:ok, _user2} = User.deactivate(user2, !user2.info.deactivated)
-
- insert(:user, %{local: false, nickname: "u@peer1.com"})
- insert(:user, %{local: false, nickname: "u@peer2.com"})
-
- {:ok, _} = CommonAPI.post(user, %{"status" => "cofe"})
-
- # Stats should count users with missing or nil `info.deactivated` value
-
- {:ok, _user} =
- user.id
- |> User.get_cached_by_id()
- |> User.update_info(&Changeset.change(&1, %{deactivated: nil}))
-
- Pleroma.Stats.force_update()
-
- conn = get(conn, "/api/v1/instance")
-
- assert result = json_response(conn, 200)
-
- stats = result["stats"]
-
- assert stats
- assert stats["user_count"] == 1
- assert stats["status_count"] == 1
- assert stats["domain_count"] == 2
- end
-
- test "get peers", %{conn: conn} do
- insert(:user, %{local: false, nickname: "u@peer1.com"})
- insert(:user, %{local: false, nickname: "u@peer2.com"})
-
- Pleroma.Stats.force_update()
-
- conn = get(conn, "/api/v1/instance/peers")
-
- assert result = json_response(conn, 200)
-
- assert ["peer1.com", "peer2.com"] == Enum.sort(result)
- 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
test "preserves parameters in link headers", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity1} =
CommonAPI.post(other_user, %{
"status" => "hi @#{user.nickname}",
"visibility" => "public"
})
{:ok, activity2} =
CommonAPI.post(other_user, %{
"status" => "hi @#{user.nickname}",
"visibility" => "public"
})
notification1 = Repo.get_by(Notification, activity_id: activity1.id)
notification2 = Repo.get_by(Notification, activity_id: activity2.id)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/notifications", %{media_only: true})
assert [link_header] = get_resp_header(conn, "link")
assert link_header =~ ~r/media_only=true/
assert link_header =~ ~r/min_id=#{notification2.id}/
assert link_header =~ ~r/max_id=#{notification1.id}/
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
test "GET /api/v1/accounts/:id/identity_proofs", %{conn: conn} do
user = insert(:user)
res =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/#{user.id}/identity_proofs")
|> json_response(200)
assert res == []
end
test "GET /api/v1/endorsements", %{conn: conn} do
user = insert(:user)
res =
conn
|> assign(:user, user)
|> get("/api/v1/endorsements")
|> json_response(200)
assert res == []
end
test "GET /api/v1/trends", %{conn: conn} do
user = insert(:user)
res =
conn
|> assign(:user, user)
|> get("/api/v1/trends")
|> json_response(200)
assert res == []
end
end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Nov 1, 12:10 AM (17 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1801938
Default Alt Text
(48 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline