diff options
Diffstat (limited to 'lib/pleroma/web/mastodon_api')
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 123 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_socket.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/account_view.ex | 27 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/filter_view.ex | 27 |
4 files changed, 142 insertions, 41 deletions
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index f482de6fd..f2fcc76ad 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -2,11 +2,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller alias Pleroma.{Repo, Object, Activity, User, Notification, Stats} alias Pleroma.Web - alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView} + alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView, FilterView} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.CommonAPI alias Pleroma.Web.OAuth.{Authorization, Token, App} + alias Pleroma.Web.MediaProxy alias Comeonin.Pbkdf2 import Ecto.Query require Logger @@ -124,7 +125,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end @instance Application.get_env(:pleroma, :instance) - @mastodon_api_level "2.3.3" + @mastodon_api_level "2.4.3" def masto_instance(conn, _params) do response = %{ @@ -653,9 +654,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do json(conn, %{}) end - def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do - accounts = User.search(query, params["resolve"] == "true") - + def status_search(query) do fetched = if Regex.match?(~r/https?:/, query) do with {:ok, object} <- ActivityPub.fetch_object_from_id(query) do @@ -680,7 +679,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do order_by: [desc: :id] ) - statuses = Repo.all(q) ++ fetched + Repo.all(q) ++ fetched + end + + def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do + accounts = User.search(query, params["resolve"] == "true") + + statuses = status_search(query) tags_path = Web.base_url() <> "/tag/" @@ -704,31 +709,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do accounts = User.search(query, params["resolve"] == "true") - 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"])] - else - _e -> [] - end - end || [] - - q = - from( - a in Activity, - where: fragment("?->>'type' = 'Create'", a.data), - where: "https://www.w3.org/ns/activitystreams#Public" in a.recipients, - where: - fragment( - "to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)", - a.data, - ^query - ), - limit: 20, - order_by: [desc: :id] - ) - - statuses = Repo.all(q) ++ fetched + statuses = status_search(query) tags = String.split(query) @@ -850,9 +831,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> Map.put("type", "Create") |> Map.put("blocking_user", user) - # adding title is a hack to not make empty lists function like a public timeline + # we must filter the following list for the user to avoid leaking statuses the user + # does not actually have permission to see (for more info, peruse security issue #270). + following_to = + following + |> Enum.filter(fn x -> x in user.following end) + activities = - ActivityPub.fetch_activities([title | following], params) + ActivityPub.fetch_activities_bounded(following_to, following, params) |> Enum.reverse() conn @@ -1044,6 +1030,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do NaiveDateTime.to_iso8601(created_at) |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false) + id = id |> to_string + case activity.data["type"] do "Create" -> %{ @@ -1089,6 +1077,65 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def get_filters(%{assigns: %{user: user}} = conn, params) do + filters = Pleroma.Filter.get_filters(user) + res = FilterView.render("filters.json", filters: filters) + json(conn, res) + end + + def create_filter( + %{assigns: %{user: user}} = conn, + %{"phrase" => phrase, "context" => context} = params + ) do + query = %Pleroma.Filter{ + user_id: user.id, + phrase: phrase, + context: context, + hide: Map.get(params, "irreversible", nil), + whole_word: Map.get(params, "boolean", true) + # expires_at + } + + {:ok, response} = Pleroma.Filter.create(query) + res = FilterView.render("filter.json", filter: response) + json(conn, res) + end + + def get_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id} = params) do + filter = Pleroma.Filter.get(filter_id, user) + res = FilterView.render("filter.json", filter: filter) + json(conn, res) + end + + def update_filter( + %{assigns: %{user: user}} = conn, + %{"phrase" => phrase, "context" => context, "id" => filter_id} = params + ) do + query = %Pleroma.Filter{ + user_id: user.id, + filter_id: filter_id, + phrase: phrase, + context: context, + hide: Map.get(params, "irreversible", nil), + whole_word: Map.get(params, "boolean", true) + # expires_at + } + + {:ok, response} = Pleroma.Filter.update(query) + res = FilterView.render("filter.json", filter: response) + json(conn, res) + end + + def delete_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id} = params) do + query = %Pleroma.Filter{ + user_id: user.id, + filter_id: filter_id + } + + {:ok, response} = Pleroma.Filter.delete(query) + json(conn, %{}) + end + def errors(conn, _) do conn |> put_status(500) @@ -1125,6 +1172,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end ) end) + |> Enum.map(fn x -> + Map.put(x, "avatar", MediaProxy.url(x["avatar"])) + end) + |> Enum.map(fn x -> + Map.put(x, "avatar_static", MediaProxy.url(x["avatar_static"])) + end) conn |> json(data2) @@ -1135,4 +1188,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do json(conn, []) end end + + def filters(conn, _) do + json(conn, []) + end end diff --git a/lib/pleroma/web/mastodon_api/mastodon_socket.ex b/lib/pleroma/web/mastodon_api/mastodon_socket.ex index 174293906..bc628ba56 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_socket.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_socket.ex @@ -23,16 +23,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonSocket do "public:local:media", "user", "direct", - "list" + "list", + "hashtag" ] <- params["stream"] do topic = if stream == "list", do: "list:#{params["list"]}", else: stream + socket_stream = if stream == "hashtag", do: "hashtag:#{params["tag"]}", else: stream socket = socket |> assign(:topic, topic) |> assign(:user, user) - Pleroma.Web.Streamer.add_socket(params["stream"], socket) + Pleroma.Web.Streamer.add_socket(socket_stream, socket) {:ok, socket} else _e -> :error diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index d9edcae7f..7915933be 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do image = User.avatar_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) + bot = (user.info["source_data"]["type"] || "Person") in ["Application", "Service"] emojis = (user.info["source_data"]["tag"] || []) @@ -26,9 +27,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do } end) + fields = + (user.info["source_data"]["attachment"] || []) + |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end) + |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end) + %{ id: to_string(user.id), - username: hd(String.split(user.nickname, "@")), + username: username_from_nickname(user.nickname), acct: user.nickname, display_name: user.name || user.nickname, locked: user_info.locked, @@ -43,11 +49,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do header: header, header_static: header, emojis: emojis, - fields: [], + fields: fields, + bot: bot, source: %{ note: "", - privacy: "public", - sensitive: "false" + privacy: user_info.default_scope, + sensitive: false } } end @@ -56,7 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do %{ id: to_string(user.id), acct: user.nickname, - username: hd(String.split(user.nickname, "@")), + username: username_from_nickname(user.nickname), url: user.ap_id } end @@ -68,12 +75,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do followed_by: User.following?(target, user), blocking: User.blocks?(user, target), muting: false, + muting_notifications: false, requested: false, - domain_blocking: false + domain_blocking: false, + showing_reblogs: false } end def render("relationships.json", %{user: user, targets: targets}) do render_many(targets, AccountView, "relationship.json", user: user, as: :target) end + + defp username_from_nickname(string) when is_binary(string) do + hd(String.split(string, "@")) + end + + defp username_from_nickname(_), do: nil end diff --git a/lib/pleroma/web/mastodon_api/views/filter_view.ex b/lib/pleroma/web/mastodon_api/views/filter_view.ex new file mode 100644 index 000000000..6bd687d46 --- /dev/null +++ b/lib/pleroma/web/mastodon_api/views/filter_view.ex @@ -0,0 +1,27 @@ +defmodule Pleroma.Web.MastodonAPI.FilterView do + use Pleroma.Web, :view + alias Pleroma.Web.MastodonAPI.FilterView + alias Pleroma.Web.CommonAPI.Utils + + def render("filters.json", %{filters: filters} = opts) do + render_many(filters, FilterView, "filter.json", opts) + end + + def render("filter.json", %{filter: filter}) do + expires_at = + if filter.expires_at do + Utils.to_masto_date(filter.expires_at) + else + nil + end + + %{ + id: to_string(filter.filter_id), + phrase: filter.phrase, + context: filter.context, + expires_at: expires_at, + irreversible: filter.hide, + whole_word: false + } + end +end |