X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fmastodon_api%2Fmastodon_api_controller.ex;h=0726e6ac48beed8ffcab640615a8970d502926d6;hb=4d3655c47959d7b9bfb3eb7316a8b7ad9010288e;hp=665b7543769ac5f59b22d1414f081c7ebe219d74;hpb=c6d5f189d9847b0c23d8150f41c05d87402680eb;p=akkoma diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 665b75437..0726e6ac4 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -1,3 +1,7 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller alias Pleroma.{Repo, Object, Activity, User, Notification, Stats} @@ -110,7 +114,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def user(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do - with %User{} = user <- Repo.get(User, id) do + with %User{} = user <- Repo.get(User, id), + true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do account = AccountView.render("account.json", %{user: user, for: for_user}) json(conn, account) else @@ -251,13 +256,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do with %User{} = user <- Repo.get(User, params["id"]) do - # Since Pleroma has no "pinned" posts feature, we'll just set an empty list here - activities = - if params["pinned"] == "true" do - [] - else - ActivityPub.fetch_user_activities(user, reading_user, params) - end + activities = ActivityPub.fetch_user_activities(user, reading_user, params) conn |> add_link_headers(:user_statuses, activities, params["id"]) @@ -342,7 +341,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do params = params |> Map.put("in_reply_to_status_id", params["in_reply_to_id"]) - |> Map.put("no_attachment_links", true) idempotency_key = case get_req_header(conn, "idempotency-key") do @@ -379,7 +377,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _unannounce, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do conn |> put_view(StatusView) |> try_render("status.json", %{activity: activity, for: user, as: :activity}) @@ -388,7 +386,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do conn |> put_view(StatusView) |> try_render("status.json", %{activity: activity, for: user, as: :activity}) @@ -397,7 +395,50 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do + %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do + conn + |> put_view(StatusView) + |> try_render("status.json", %{activity: activity, for: user, as: :activity}) + end + end + + def pin_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do + with {:ok, activity} <- CommonAPI.pin(ap_id_or_id, user) do + conn + |> put_view(StatusView) + |> try_render("status.json", %{activity: activity, for: user, as: :activity}) + else + {:error, reason} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(:bad_request, Jason.encode!(%{"error" => reason})) + end + end + + def unpin_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do + with {:ok, activity} <- CommonAPI.unpin(ap_id_or_id, user) do + conn + |> put_view(StatusView) + |> try_render("status.json", %{activity: activity, for: user, as: :activity}) + end + end + + def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %Activity{} = activity <- Repo.get(Activity, id), + %User{} = user <- User.get_by_nickname(user.nickname), + true <- ActivityPub.visible_for_user?(activity, user), + {:ok, user} <- User.bookmark(user, activity.data["object"]["id"]) do + conn + |> put_view(StatusView) + |> try_render("status.json", %{activity: activity, for: user, as: :activity}) + end + end + + def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %Activity{} = activity <- Repo.get(Activity, id), + %User{} = user <- User.get_by_nickname(user.nickname), + true <- ActivityPub.visible_for_user?(activity, user), + {:ok, user} <- User.unbookmark(user, activity.data["object"]["id"]) do conn |> put_view(StatusView) |> try_render("status.json", %{activity: activity, for: user, as: :activity}) @@ -480,7 +521,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def upload(%{assigns: %{user: user}} = conn, %{"file" => file} = data) do with {:ok, object} <- - ActivityPub.upload(file, + ActivityPub.upload( + file, actor: User.ap_id(user), description: Map.get(data, "description") ) do @@ -521,15 +563,34 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do local_only = params["local"] in [true, "True", "true", "1"] - params = + tags = + [params["tag"], params["any"]] + |> List.flatten() + |> Enum.uniq() + |> Enum.filter(& &1) + |> Enum.map(&String.downcase(&1)) + + tag_all = + params["all"] || + [] + |> Enum.map(&String.downcase(&1)) + + tag_reject = + params["none"] || + [] + |> Enum.map(&String.downcase(&1)) + + query_params = params |> Map.put("type", "Create") |> Map.put("local_only", local_only) |> Map.put("blocking_user", user) - |> Map.put("tag", String.downcase(params["tag"])) + |> Map.put("tag", tags) + |> Map.put("tag_all", tag_all) + |> Map.put("tag_reject", tag_reject) activities = - ActivityPub.fetch_public_activities(params) + ActivityPub.fetch_public_activities(query_params) |> Enum.reverse() conn @@ -699,11 +760,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - # TODO: Use proper query def blocks(%{assigns: %{user: user}} = conn, _) do - with blocked_users <- user.info.blocks || [], - accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do - res = AccountView.render("accounts.json", users: accounts, for: user, as: :user) + with blocked_accounts <- User.blocked_users(user) do + res = AccountView.render("accounts.json", users: blocked_accounts, for: user, as: :user) json(conn, res) end end @@ -722,11 +781,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do json(conn, %{}) end - def status_search(query) do + def status_search(user, query) do fetched = if Regex.match?(~r/https?:/, query) do - with {:ok, object} <- ActivityPub.fetch_object_from_id(query) do - [Activity.get_create_activity_by_object_ap_id(object.data["id"])] + with {:ok, object} <- ActivityPub.fetch_object_from_id(query), + %Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]), + true <- ActivityPub.visible_for_user?(activity, user) do + [activity] else _e -> [] end @@ -751,9 +812,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = User.search(query, params["resolve"] == "true") + accounts = User.search(query, params["resolve"] == "true", user) - statuses = status_search(query) + statuses = status_search(user, query) tags_path = Web.base_url() <> "/tag/" @@ -775,9 +836,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = User.search(query, params["resolve"] == "true") + accounts = User.search(query, params["resolve"] == "true", user) - statuses = status_search(query) + statuses = status_search(user, query) tags = String.split(query) @@ -796,16 +857,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = User.search(query, params["resolve"] == "true") + accounts = User.search(query, params["resolve"] == "true", user) res = AccountView.render("accounts.json", users: accounts, for: user, as: :user) json(conn, res) end - def favourites(%{assigns: %{user: user}} = conn, _) do + 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) @@ -814,6 +875,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do ActivityPub.fetch_public_activities(params) |> Enum.reverse() + conn + |> add_link_headers(:favourites, activities) + |> put_view(StatusView) + |> render("index.json", %{activities: activities, for: user, as: :activity}) + end + + def bookmarks(%{assigns: %{user: user}} = conn, _) do + user = Repo.get(User, user.id) + + activities = + user.bookmarks + |> Enum.map(fn id -> Activity.get_create_by_object_ap_id(id) end) + |> Enum.reverse() + conn |> put_view(StatusView) |> render("index.json", %{activities: activities, for: user, as: :activity}) @@ -961,7 +1036,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do max_toot_chars: limit }, rights: %{ - delete_others_notice: !!user.info.is_moderator + delete_others_notice: !!user.info.is_moderator, + admin: !!user.info.is_admin }, compose: %{ me: "#{user.id}", @@ -1060,7 +1136,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def login(conn, _) do with {:ok, app} <- get_or_make_app() do path = - o_auth_path(conn, :authorize, + o_auth_path( + conn, + :authorize, response_type: "code", client_id: app.client_id, redirect_uri: ".", @@ -1116,7 +1194,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do actor = User.get_cached_by_ap_id(activity.data["actor"]) - parent_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + parent_activity = Activity.get_create_by_object_ap_id(activity.data["object"]) mastodon_type = Activity.mastodon_notification_type(activity) response = %{ @@ -1268,7 +1346,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do [], adapter: [ timeout: timeout, - recv_timeout: timeout + recv_timeout: timeout, + pool: :default ] ), {:ok, data} <- Jason.decode(body) do @@ -1301,6 +1380,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def status_card(conn, %{"id" => status_id}) do + with %Activity{} = activity <- Repo.get(Activity, status_id), + true <- ActivityPub.is_public?(activity) do + data = + StatusView.render( + "card.json", + Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + ) + + json(conn, data) + else + _e -> + %{} + end + end + def try_render(conn, target, params) when is_binary(target) do res = render(conn, target, params)