X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fmastodon_api%2Fmastodon_api_controller.ex;h=71390be0df0dfc5a1d968925c872ff92a253e154;hb=f85949cc696685496a8e4e17aebeb81168ede41a;hp=5cb007740bcebc66129584a7db6f32c6f1dca114;hpb=a8f1e30cb81fe17866e3ee33f5b3558dd5b33764;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 5cb007740..71390be0d 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -1,6 +1,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller alias Pleroma.{Repo, Object, Activity, User, Notification, Stats} + alias Pleroma.Object.Fetcher alias Pleroma.Web alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView, FilterView} alias Pleroma.Web.ActivityPub.ActivityPub @@ -32,75 +33,55 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - def update_credentials(%{assigns: %{user: user}} = conn, params) do - original_user = user - - avatar_upload_limit = - Application.get_env(:pleroma, :instance) - |> Keyword.fetch(:avatar_upload_limit) - - banner_upload_limit = - Application.get_env(:pleroma, :instance) - |> Keyword.fetch(:banner_upload_limit) - - params = - if bio = params["note"] do - Map.put(params, "bio", bio) - else - params + defp add_if_present( + map, + params, + params_field, + map_field, + value_function \\ fn x -> {:ok, x} end + ) do + if Map.has_key?(params, params_field) do + case value_function.(params[params_field]) do + {:ok, new_value} -> Map.put(map, map_field, new_value) + :error -> map end + else + map + end + end - params = - if name = params["display_name"] do - Map.put(params, "name", name) - else - params - end + def update_credentials(%{assigns: %{user: user}} = conn, params) do + original_user = user - user = - if avatar = params["avatar"] do - with %Plug.Upload{} <- avatar, - {:ok, object} <- ActivityPub.upload(avatar, avatar_upload_limit), - change = Ecto.Changeset.change(user, %{avatar: object.data}), - {:ok, user} = User.update_and_set_cache(change) do - user + user_params = + %{} + |> add_if_present(params, "display_name", :name) + |> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value)} end) + |> add_if_present(params, "avatar", :avatar, fn value -> + with %Plug.Upload{} <- value, + {:ok, object} <- ActivityPub.upload(value, type: :avatar) do + {:ok, object.data} else - _e -> user + _ -> :error end - else - user - end + end) - user = - if banner = params["header"] do - with %Plug.Upload{} <- banner, - {:ok, object} <- ActivityPub.upload(banner, banner_upload_limit), - new_info <- Map.put(user.info, "banner", object.data), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do - user + info_params = + %{} + |> add_if_present(params, "locked", :locked, fn value -> {:ok, value == "true"} end) + |> add_if_present(params, "header", :banner, fn value -> + with %Plug.Upload{} <- value, + {:ok, object} <- ActivityPub.upload(value, type: :banner) do + {:ok, object.data} else - _e -> user + _ -> :error end - else - user - end + end) - user = - if locked = params["locked"] do - with locked <- locked == "true", - new_info <- Map.put(user.info, "locked", locked), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do - user - else - _e -> user - end - else - user - end + info_cng = User.Info.mastodon_profile_update(user.info, info_params) - with changeset <- User.update_changeset(user, params), + with changeset <- User.update_changeset(user, user_params), + changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng), {:ok, user} <- User.update_and_set_cache(changeset) do if original_user != user do CommonAPI.update(user) @@ -132,22 +113,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - @instance Application.get_env(:pleroma, :instance) @mastodon_api_level "2.5.0" def masto_instance(conn, _params) do + instance = Pleroma.Config.get(:instance) + response = %{ uri: Web.base_url(), - title: Keyword.get(@instance, :name), - description: Keyword.get(@instance, :description), - version: "#{@mastodon_api_level} (compatible; #{Keyword.get(@instance, :version)})", - email: Keyword.get(@instance, :email), + 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: String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws") }, stats: Stats.get_stats(), thumbnail: Web.base_url() <> "/instance/thumbnail.jpeg", - max_toot_chars: Keyword.get(@instance, :limit) + max_toot_chars: Keyword.get(instance, :limit) } json(conn, response) @@ -277,9 +259,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - def dm_timeline(%{assigns: %{user: user}} = conn, _params) do + def dm_timeline(%{assigns: %{user: user}} = conn, params) do query = - ActivityPub.fetch_activities_query([user.ap_id], %{"type" => "Create", visibility: "direct"}) + ActivityPub.fetch_activities_query( + [user.ap_id], + Map.merge(params, %{"type" => "Create", visibility: "direct"}) + ) activities = Repo.all(query) @@ -443,6 +428,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do render(conn, AccountView, "relationships.json", %{user: user, targets: targets}) end + # Instead of returning a 400 when no "id" params is present, Mastodon returns an empty array. + def relationships(%{assigns: %{user: user}} = conn, _) do + conn + |> json([]) + end + def update_media(%{assigns: %{user: _}} = conn, data) do with %Object{} = object <- Repo.get(Object, data["id"]), true <- is_binary(data["description"]), @@ -461,19 +452,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def upload(%{assigns: %{user: _}} = conn, %{"file" => file} = data) do - with {:ok, object} <- ActivityPub.upload(file) do - objdata = - if Map.has_key?(data, "description") do - Map.put(object.data, "name", data["description"]) - else - object.data - end - - change = Object.change(object, %{data: objdata}) + with {:ok, object} <- ActivityPub.upload(file, description: Map.get(data, "description")) do + change = Object.change(object, %{data: object.data}) {:ok, object} = Repo.update(change) objdata = - objdata + object.data |> Map.put("id", object.id) render(conn, StatusView, "attachment.json", %{attachment: objdata}) @@ -481,7 +465,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def favourited_by(conn, %{"id" => id}) do - with %Activity{data: %{"object" => %{"likes" => likes}}} <- Repo.get(Activity, id) do + with %Activity{data: %{"object" => object}} <- Repo.get(Activity, id), + %Object{data: %{"likes" => likes}} <- Object.normalize(object) do q = from(u in User, where: u.ap_id in ^likes) users = Repo.all(q) render(conn, AccountView, "accounts.json", %{users: users, as: :user}) @@ -491,7 +476,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def reblogged_by(conn, %{"id" => id}) do - with %Activity{data: %{"object" => %{"announcements" => announces}}} <- Repo.get(Activity, id) do + with %Activity{data: %{"object" => object}} <- Repo.get(Activity, id), + %Object{data: %{"announcements" => announces}} <- Object.normalize(object) do q = from(u in User, where: u.ap_id in ^announces) users = Repo.all(q) render(conn, AccountView, "accounts.json", %{users: users, as: :user}) @@ -581,15 +567,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - @activitypub Application.get_env(:pleroma, :activitypub) - @follow_handshake_timeout Keyword.get(@activitypub, :follow_handshake_timeout) - def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do with %User{} = followed <- Repo.get(User, id), {:ok, follower} <- User.maybe_direct_follow(follower, followed), {:ok, _activity} <- ActivityPub.follow(follower, followed), {:ok, follower, followed} <- - User.wait_and_refresh(@follow_handshake_timeout, follower, followed) do + User.wait_and_refresh( + Pleroma.Config.get([:activitypub, :follow_handshake_timeout]), + follower, + followed + ) do render(conn, AccountView, "relationship.json", %{user: follower, target: followed}) else {:error, message} -> @@ -648,7 +635,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do # TODO: Use proper query def blocks(%{assigns: %{user: user}} = conn, _) do - with blocked_users <- user.info["blocks"] || [], + 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) json(conn, res) @@ -656,7 +643,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def domain_blocks(%{assigns: %{user: %{info: info}}} = conn, _) do - json(conn, info["domain_blocks"] || []) + json(conn, info.domain_blocks || []) end def block_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do @@ -672,7 +659,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def status_search(query) do fetched = if Regex.match?(~r/https?:/, query) do - with {:ok, object} <- ActivityPub.fetch_object_from_id(query) do + with {:ok, object} <- Fetcher.fetch_object_from_id(query) do [Activity.get_create_activity_by_object_ap_id(object.data["id"])] else _e -> [] @@ -880,6 +867,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do if user && token do mastodon_emoji = mastodonized_emoji() + limit = Pleroma.Config.get([:instance, :limit]) + accounts = Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user})) @@ -899,14 +888,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do auto_play_gif: false, display_sensitive_media: false, reduce_motion: false, - max_toot_chars: Keyword.get(@instance, :limit) + max_toot_chars: limit }, rights: %{ - delete_others_notice: !!user.info["is_moderator"] + delete_others_notice: !!user.info.is_moderator }, compose: %{ me: "#{user.id}", - default_privacy: user.info["default_scope"] || "public", + default_privacy: user.info.default_scope, default_sensitive: false }, media_attachments: %{ @@ -926,7 +915,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do ] }, settings: - Map.get(user.info, "settings") || + Map.get(user.info, :settings) || %{ onboarded: true, home: %{ @@ -959,7 +948,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do push_subscription: nil, accounts: accounts, custom_emojis: mastodon_emoji, - char_limit: Keyword.get(@instance, :limit) + char_limit: limit } |> Jason.encode!() @@ -998,7 +987,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: ".", @@ -1169,18 +1160,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do |> json("Something went wrong") end - @suggestions Application.get_env(:pleroma, :suggestions) - def suggestions(%{assigns: %{user: user}} = conn, _) do - if Keyword.get(@suggestions, :enabled, false) do - api = Keyword.get(@suggestions, :third_party_engine, "") - timeout = Keyword.get(@suggestions, :timeout, 5000) - limit = Keyword.get(@suggestions, :limit, 23) - - host = - Application.get_env(:pleroma, Pleroma.Web.Endpoint) - |> Keyword.get(:url) - |> Keyword.get(:host) + suggestions = Pleroma.Config.get(:suggestions) + + if Keyword.get(suggestions, :enabled, false) do + api = Keyword.get(suggestions, :third_party_engine, "") + timeout = Keyword.get(suggestions, :timeout, 5000) + limit = Keyword.get(suggestions, :limit, 23) + + host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host]) user = user.nickname url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user)