Merge branch 'develop' into exclusive-lists

This commit is contained in:
nicole mikołajczyk 2026-03-10 12:03:13 +00:00
commit d1787966a6
61 changed files with 703 additions and 546 deletions

View file

@ -0,0 +1 @@
Various bookmark folders-related improvements

View file

@ -0,0 +1 @@
Gopher: Fix Ranch listener not being stopped properly on Pleroma restart when database configuration is enabled

View file

View file

View file

@ -0,0 +1 @@
Update comment for prepare_object, rename prepare_outgoing

View file

@ -74,7 +74,7 @@ Pleroma does not process remote images and therefore cannot include fields such
The `GET /api/v1/bookmarks` endpoint accepts optional parameter `folder_id` for bookmark folder ID. The `GET /api/v1/bookmarks` endpoint accepts optional parameter `folder_id` for bookmark folder ID.
The `POST /api/v1/statuses/:id/bookmark` endpoint accepts optional parameter `folder_id` for bookmark folder ID. The `POST /api/v1/statuses/:id/bookmark` endpoint accepts optional parameter `folder_id` for bookmark folder ID. Bookmarking an already bookmarked post will update the folder association, or remove it if `folder_id` is omitted or `null`.
## Accounts ## Accounts

View file

@ -19,7 +19,7 @@ defmodule Pleroma.Bookmark do
schema "bookmarks" do schema "bookmarks" do
belongs_to(:user, User, type: FlakeId.Ecto.CompatType) belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType) belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
belongs_to(:folder, BookmarkFolder, type: FlakeId.Ecto.CompatType) belongs_to(:folder, BookmarkFolder, type: FlakeId.Ecto.Type)
timestamps() timestamps()
end end
@ -38,7 +38,7 @@ defmodule Pleroma.Bookmark do
|> validate_required([:user_id, :activity_id]) |> validate_required([:user_id, :activity_id])
|> unique_constraint(:activity_id, name: :bookmarks_user_id_activity_id_index) |> unique_constraint(:activity_id, name: :bookmarks_user_id_activity_id_index)
|> Repo.insert( |> Repo.insert(
on_conflict: [set: [folder_id: folder_id]], on_conflict: [set: [folder_id: folder_id, updated_at: NaiveDateTime.utc_now()]],
conflict_target: [:user_id, :activity_id] conflict_target: [:user_id, :activity_id]
) )
end end
@ -76,11 +76,4 @@ defmodule Pleroma.Bookmark do
|> Repo.one() |> Repo.one()
|> Repo.delete() |> Repo.delete()
end end
def set_folder(bookmark, folder_id) do
bookmark
|> cast(%{folder_id: folder_id}, [:folder_id])
|> validate_required([:folder_id])
|> Repo.update()
end
end end

View file

@ -14,7 +14,7 @@ defmodule Pleroma.BookmarkFolder do
alias Pleroma.User alias Pleroma.User
@type t :: %__MODULE__{} @type t :: %__MODULE__{}
@primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true} @primary_key {:id, FlakeId.Ecto.Type, autogenerate: true}
schema "bookmark_folders" do schema "bookmark_folders" do
field(:name, :string) field(:name, :string)

View file

@ -21,10 +21,13 @@ defmodule Pleroma.Gopher.Server do
def init([ip, port]) do def init([ip, port]) do
Logger.info("Starting gopher server on #{port}") Logger.info("Starting gopher server on #{port}")
Process.flag(:trap_exit, true)
listener = :gopher
{:ok, _pid} = {:ok, _pid} =
:ranch.start_listener( :ranch.start_listener(
:gopher, listener,
:ranch_tcp, :ranch_tcp,
%{ %{
num_acceptors: 100, num_acceptors: 100,
@ -35,7 +38,11 @@ defmodule Pleroma.Gopher.Server do
[] []
) )
{:ok, %{ip: ip, port: port}} {:ok, %{ip: ip, port: port, listener: listener}}
end
def terminate(_reason, state) do
:ranch.stop_listener(state.listener)
end end
end end

View file

@ -342,7 +342,7 @@ defmodule Pleroma.User.Backup do
dir, dir,
"outbox", "outbox",
fn a -> fn a ->
with {:ok, activity} <- Transmogrifier.prepare_outgoing(a.data) do with {:ok, activity} <- Transmogrifier.prepare_activity(a.data) do
{:ok, Map.delete(activity, "@context")} {:ok, Map.delete(activity, "@context")}
end end
end end

View file

@ -79,7 +79,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
Determine if an activity can be represented by running it through Transmogrifier. Determine if an activity can be represented by running it through Transmogrifier.
""" """
def representable?(%Activity{} = activity) do def representable?(%Activity{} = activity) do
with {:ok, _data} <- @transmogrifier_impl.prepare_outgoing(activity.data) do with {:ok, _data} <- @transmogrifier_impl.prepare_activity(activity.data) do
true true
else else
_e -> _e ->
@ -102,14 +102,14 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
Logger.debug("Federating #{ap_id} to #{inbox}") Logger.debug("Federating #{ap_id} to #{inbox}")
uri = %{path: path} = URI.parse(inbox) uri = %{path: path} = URI.parse(inbox)
{:ok, data} = @transmogrifier_impl.prepare_outgoing(activity.data) {:ok, data} = @transmogrifier_impl.prepare_activity(activity.data)
{actor, data} = {actor, data} =
with {_, false} <- {:actor_changed?, data["actor"] != activity.data["actor"]} do with {_, false} <- {:actor_changed?, data["actor"] != activity.data["actor"]} do
{actor, data} {actor, data}
else else
{:actor_changed?, true} -> {:actor_changed?, true} ->
# If prepare_outgoing changes the actor, re-get it from the db # If prepare_activity changes the actor, re-get it from the db
new_actor = User.get_cached_by_ap_id(data["actor"]) new_actor = User.get_cached_by_ap_id(data["actor"])
{new_actor, data} {new_actor, data}
end end

View file

@ -783,7 +783,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def set_replies(obj_data), do: obj_data def set_replies(obj_data), do: obj_data
# Prepares the object of an outgoing create activity. # Prepares and sanitizes the object for federation.
def prepare_object(object) do def prepare_object(object) do
object object
|> add_hashtags |> add_hashtags
@ -824,7 +824,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# internal -> Mastodon # internal -> Mastodon
# """ # """
def prepare_outgoing(%{"type" => activity_type, "object" => object_id} = data) def prepare_activity(%{"type" => activity_type, "object" => object_id} = data)
when activity_type in ["Create", "Listen"] do when activity_type in ["Create", "Listen"] do
object = object =
object_id object_id
@ -840,7 +840,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:ok, data} {:ok, data}
end end
def prepare_outgoing(%{"type" => "Update", "object" => %{"type" => objtype} = object} = data) def prepare_activity(%{"type" => "Update", "object" => %{"type" => objtype} = object} = data)
when objtype in Pleroma.Constants.updatable_object_types() do when objtype in Pleroma.Constants.updatable_object_types() do
data = data =
data data
@ -851,7 +851,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:ok, data} {:ok, data}
end end
def prepare_outgoing(%{"type" => "Update", "object" => %{"type" => objtype} = object} = data) def prepare_activity(%{"type" => "Update", "object" => %{"type" => objtype} = object} = data)
when objtype in Pleroma.Constants.actor_types() do when objtype in Pleroma.Constants.actor_types() do
object = object =
object object
@ -868,11 +868,11 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:ok, data} {:ok, data}
end end
def prepare_outgoing(%{"type" => "Update", "object" => %{}} = data) do def prepare_activity(%{"type" => "Update", "object" => %{}} = data) do
raise "Requested to serve an Update for non-updateable object type: #{inspect(data)}" raise "Requested to serve an Update for non-updateable object type: #{inspect(data)}"
end end
def prepare_outgoing(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do def prepare_activity(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do
object = object =
object_id object_id
|> Object.normalize(fetch: false) |> Object.normalize(fetch: false)
@ -895,7 +895,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# Mastodon Accept/Reject requires a non-normalized object containing the actor URIs, # Mastodon Accept/Reject requires a non-normalized object containing the actor URIs,
# because of course it does. # because of course it does.
def prepare_outgoing(%{"type" => "Accept"} = data) do def prepare_activity(%{"type" => "Accept"} = data) do
with follow_activity <- Activity.normalize(data["object"]) do with follow_activity <- Activity.normalize(data["object"]) do
object = %{ object = %{
"actor" => follow_activity.actor, "actor" => follow_activity.actor,
@ -913,7 +913,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end end
end end
def prepare_outgoing(%{"type" => "Reject"} = data) do def prepare_activity(%{"type" => "Reject"} = data) do
with follow_activity <- Activity.normalize(data["object"]) do with follow_activity <- Activity.normalize(data["object"]) do
object = %{ object = %{
"actor" => follow_activity.actor, "actor" => follow_activity.actor,
@ -931,7 +931,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end end
end end
def prepare_outgoing(%{"type" => "Flag"} = data) do def prepare_activity(%{"type" => "Flag"} = data) do
with {:ok, stripped_activity} <- Utils.strip_report_status_data(data), with {:ok, stripped_activity} <- Utils.strip_report_status_data(data),
stripped_activity <- Utils.maybe_anonymize_reporter(stripped_activity), stripped_activity <- Utils.maybe_anonymize_reporter(stripped_activity),
stripped_activity <- Map.merge(stripped_activity, Utils.make_json_ld_header()) do stripped_activity <- Map.merge(stripped_activity, Utils.make_json_ld_header()) do
@ -939,7 +939,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end end
end end
def prepare_outgoing(%{"type" => _type} = data) do def prepare_activity(%{"type" => _type} = data) do
data = data =
data data
|> strip_internal_fields |> strip_internal_fields

View file

@ -7,5 +7,5 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.API do
Behaviour for the subset of Transmogrifier used by Publisher. Behaviour for the subset of Transmogrifier used by Publisher.
""" """
@callback prepare_outgoing(map()) :: {:ok, map()} | {:error, term()} @callback prepare_activity(map()) :: {:ok, map()} | {:error, term()}
end end

View file

@ -19,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
end end
def render("object.json", %{object: %Activity{} = activity}) do def render("object.json", %{object: %Activity{} = activity}) do
{:ok, ap_data} = Transmogrifier.prepare_outgoing(activity.data) {:ok, ap_data} = Transmogrifier.prepare_activity(activity.data)
ap_data ap_data
end end

View file

@ -283,7 +283,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
}) do }) do
collection = collection =
Enum.map(activities, fn activity -> Enum.map(activities, fn activity ->
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data) {:ok, data} = Transmogrifier.prepare_activity(activity.data)
data data
end) end)

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do defmodule Pleroma.Web.ApiSpec.PleromaUtilOperation do
alias OpenApiSpex.Operation alias OpenApiSpex.Operation
alias OpenApiSpex.Schema alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.ApiError alias Pleroma.Web.ApiSpec.Schemas.ApiError
@ -19,7 +19,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
%Operation{ %Operation{
tags: ["Custom emojis"], tags: ["Custom emojis"],
summary: "List all custom emojis", summary: "List all custom emojis",
operationId: "UtilController.emoji", operationId: "PleromaAPI.UtilController.emoji",
parameters: [], parameters: [],
responses: %{ responses: %{
200 => 200 =>
@ -48,7 +48,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
%Operation{ %Operation{
tags: ["Others"], tags: ["Others"],
summary: "Dump frontend configurations", summary: "Dump frontend configurations",
operationId: "UtilController.frontend_configurations", operationId: "PleromaAPI.UtilController.frontend_configurations",
parameters: [], parameters: [],
responses: %{ responses: %{
200 => 200 =>
@ -70,7 +70,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "Change account password", summary: "Change account password",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.change_password", operationId: "PleromaAPI.UtilController.change_password",
requestBody: request_body("Parameters", change_password_request(), required: true), requestBody: request_body("Parameters", change_password_request(), required: true),
responses: %{ responses: %{
200 => 200 =>
@ -106,7 +106,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "Change account email", summary: "Change account email",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.change_email", operationId: "PleromaAPI.UtilController.change_email",
requestBody: request_body("Parameters", change_email_request(), required: true), requestBody: request_body("Parameters", change_email_request(), required: true),
responses: %{ responses: %{
200 => 200 =>
@ -141,7 +141,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Settings"], tags: ["Settings"],
summary: "Update Notification Settings", summary: "Update Notification Settings",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.update_notification_settings", operationId: "PleromaAPI.UtilController.update_notification_settings",
parameters: [ parameters: [
Operation.parameter( Operation.parameter(
:block_from_strangers, :block_from_strangers,
@ -173,7 +173,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "Disable Account", summary: "Disable Account",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.disable_account", operationId: "PleromaAPI.UtilController.disable_account",
parameters: [ parameters: [
Operation.parameter(:password, :query, :string, "Password") Operation.parameter(:password, :query, :string, "Password")
], ],
@ -193,7 +193,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "Delete Account", summary: "Delete Account",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.delete_account", operationId: "PleromaAPI.UtilController.delete_account",
parameters: [ parameters: [
Operation.parameter(:password, :query, :string, "Password") Operation.parameter(:password, :query, :string, "Password")
], ],
@ -212,7 +212,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
def captcha_operation do def captcha_operation do
%Operation{ %Operation{
summary: "Get a captcha", summary: "Get a captcha",
operationId: "UtilController.captcha", operationId: "PleromaAPI.UtilController.captcha",
tags: ["Others"], tags: ["Others"],
parameters: [], parameters: [],
responses: %{ responses: %{
@ -226,7 +226,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "Move account", summary: "Move account",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.move_account", operationId: "PleromaAPI.UtilController.move_account",
requestBody: request_body("Parameters", move_account_request(), required: true), requestBody: request_body("Parameters", move_account_request(), required: true),
responses: %{ responses: %{
200 => 200 =>
@ -262,7 +262,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "List account aliases", summary: "List account aliases",
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
operationId: "UtilController.list_aliases", operationId: "PleromaAPI.UtilController.list_aliases",
responses: %{ responses: %{
200 => 200 =>
Operation.response("Success", "application/json", %Schema{ Operation.response("Success", "application/json", %Schema{
@ -286,7 +286,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "Add an alias to this account", summary: "Add an alias to this account",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.add_alias", operationId: "PleromaAPI.UtilController.add_alias",
requestBody: request_body("Parameters", add_alias_request(), required: true), requestBody: request_body("Parameters", add_alias_request(), required: true),
responses: %{ responses: %{
200 => 200 =>
@ -326,7 +326,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Account credentials"], tags: ["Account credentials"],
summary: "Delete an alias from this account", summary: "Delete an alias from this account",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.delete_alias", operationId: "PleromaAPI.UtilController.delete_alias",
requestBody: request_body("Parameters", delete_alias_request(), required: true), requestBody: request_body("Parameters", delete_alias_request(), required: true),
responses: %{ responses: %{
200 => 200 =>
@ -366,7 +366,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
tags: ["Others"], tags: ["Others"],
summary: "Quick status check on the instance", summary: "Quick status check on the instance",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.healthcheck", operationId: "PleromaAPI.UtilController.healthcheck",
parameters: [], parameters: [],
responses: %{ responses: %{
200 => Operation.response("Healthy", "application/json", %Schema{type: :object}), 200 => Operation.response("Healthy", "application/json", %Schema{type: :object}),
@ -376,52 +376,6 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
} }
end end
def remote_subscribe_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Remote Subscribe",
operationId: "UtilController.remote_subscribe",
parameters: [],
responses: %{200 => Operation.response("Web Page", "test/html", %Schema{type: :string})}
}
end
def remote_interaction_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Remote interaction",
operationId: "UtilController.remote_interaction",
requestBody: request_body("Parameters", remote_interaction_request(), required: true),
responses: %{
200 =>
Operation.response("Remote interaction URL", "application/json", %Schema{type: :object})
}
}
end
defp remote_interaction_request do
%Schema{
title: "RemoteInteractionRequest",
description: "POST body for remote interaction",
type: :object,
required: [:ap_id, :profile],
properties: %{
ap_id: %Schema{type: :string, description: "Profile or status ActivityPub ID"},
profile: %Schema{type: :string, description: "Remote profile webfinger"}
}
}
end
def show_subscribe_form_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Show remote subscribe form",
operationId: "UtilController.show_subscribe_form",
parameters: [],
responses: %{200 => Operation.response("Web Page", "test/html", %Schema{type: :string})}
}
end
defp delete_account_request do defp delete_account_request do
%Schema{ %Schema{
title: "AccountDeleteRequest", title: "AccountDeleteRequest",

View file

@ -0,0 +1,99 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.RemoteInteractionOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
import Pleroma.Web.ApiSpec.Helpers
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def remote_interaction_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Remote interaction",
operationId: "RemoteInteractionController.remote_interaction",
requestBody: request_body("Parameters", remote_interaction_request(), required: true),
responses: %{
200 =>
Operation.response("Remote interaction URL", "application/json", %Schema{type: :object})
}
}
end
defp remote_interaction_request do
%Schema{
title: "RemoteInteractionRequest",
description: "POST body for remote interaction",
type: :object,
required: [:ap_id, :profile],
properties: %{
ap_id: %Schema{type: :string, description: "Profile or status ActivityPub ID"},
profile: %Schema{type: :string, description: "Remote profile webfinger"}
}
}
end
def follow_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Display follow form",
operationId: "RemoteInteractionController.follow",
parameters: [],
responses: %{
200 => Operation.response("Web Page", "text/html", %Schema{type: :string}),
302 => Operation.response("Redirect to the status page", nil, nil)
}
}
end
def do_follow_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Perform follow activity",
operationId: "RemoteInteractionController.do_follow",
parameters: [],
responses: %{
200 => Operation.response("Web page", "text/html", %Schema{type: :string}),
302 => Operation.response("Redirect to the account page", nil, nil)
}
}
end
def authorize_interaction_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Authorize remote interaction",
operationId: "RemoteInteractionController.authorize_interaction",
parameters: [],
responses: %{
302 => Operation.response("Redirect to remote_interaction path", nil, nil)
}
}
end
def show_subscribe_form_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Show remote subscribe form",
operationId: "RemoteInteractionController.show_subscribe_form",
parameters: [],
responses: %{200 => Operation.response("Web Page", "text/html", %Schema{type: :string})}
}
end
def remote_subscribe_operation do
%Operation{
tags: ["Remote interaction"],
summary: "Remote Subscribe",
operationId: "RemoteInteractionController.remote_subscribe",
parameters: [],
responses: %{200 => Operation.response("Web Page", "text/html", %Schema{type: :string})}
}
end
end

View file

@ -15,12 +15,18 @@ defmodule Pleroma.Web.ApiSpec.Schemas.BookmarkFolder do
properties: %{ properties: %{
id: FlakeID, id: FlakeID,
name: %Schema{type: :string, description: "Folder name"}, name: %Schema{type: :string, description: "Folder name"},
emoji: %Schema{type: :string, description: "Folder emoji", nullable: true} emoji: %Schema{type: :string, description: "Folder emoji", nullable: true},
emoji_url: %Schema{
type: :string,
description: "URL of the folder emoji if it's a custom emoji, null otherwise",
nullable: true
}
}, },
example: %{ example: %{
"id" => "9toJCu5YZW7O7gfvH6", "id" => "9toJCu5YZW7O7gfvH6",
"name" => "Read later", "name" => "Read later",
"emoji" => nil "emoji" => nil,
"emoji_url" => nil
} }
}) })
end end

View file

@ -26,7 +26,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
alias Pleroma.Web.OAuth.OAuthController alias Pleroma.Web.OAuth.OAuthController
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.Plugs.RateLimiter alias Pleroma.Web.Plugs.RateLimiter
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.Registration
alias Pleroma.Web.Utils.Params alias Pleroma.Web.Utils.Params
plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false) plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
@ -111,8 +111,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
_params _params
) do ) do
with :ok <- validate_email_param(params), with :ok <- validate_email_param(params),
:ok <- TwitterAPI.validate_captcha(app, params), :ok <- Registration.validate_captcha(app, params),
{:ok, user} <- TwitterAPI.register_user(params), {:ok, user} <- Registration.register_user(params),
{_, {:ok, token}} <- {_, {:ok, token}} <-
{:login, OAuthController.login(user, app, app.scopes)} do {:login, OAuthController.login(user, app, app.scopes)} do
OAuthController.after_token_exchange(conn, %{user: user, token: token}) OAuthController.after_token_exchange(conn, %{user: user, token: token})

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
import Pleroma.Web.ControllerHelper, only: [json_response: 3] import Pleroma.Web.ControllerHelper, only: [json_response: 3]
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.Registration
action_fallback(Pleroma.Web.MastodonAPI.FallbackController) action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
@ -17,7 +17,7 @@ defmodule Pleroma.Web.MastodonAPI.AuthController do
def password_reset(conn, params) do def password_reset(conn, params) do
nickname_or_email = params["email"] || params["nickname"] nickname_or_email = params["email"] || params["nickname"]
TwitterAPI.password_reset(nickname_or_email) Registration.password_reset(nickname_or_email)
json_response(conn, :no_content, "") json_response(conn, :no_content, "")
end end

View file

@ -81,10 +81,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action in [:pin, :unpin]) plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action in [:pin, :unpin])
# Note: scope not present in Mastodon: read:bookmarks
plug(OAuthScopesPlug, %{scopes: ["read:bookmarks"]} when action == :bookmarks) plug(OAuthScopesPlug, %{scopes: ["read:bookmarks"]} when action == :bookmarks)
# Note: scope not present in Mastodon: write:bookmarks
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark] %{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark]

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.PasswordController do defmodule Pleroma.Web.OAuth.PasswordController do
@moduledoc """ @moduledoc """
The module contains functions for password reset. The module contains functions for password reset.
""" """
@ -16,7 +16,7 @@ defmodule Pleroma.Web.TwitterAPI.PasswordController do
alias Pleroma.PasswordResetToken alias Pleroma.PasswordResetToken
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.Registration
plug(Pleroma.Web.Plugs.RateLimiter, [name: :request] when action == :request) plug(Pleroma.Web.Plugs.RateLimiter, [name: :request] when action == :request)
@ -24,7 +24,7 @@ defmodule Pleroma.Web.TwitterAPI.PasswordController do
def request(conn, params) do def request(conn, params) do
nickname_or_email = params["email"] || params["nickname"] nickname_or_email = params["email"] || params["nickname"]
TwitterAPI.password_reset(nickname_or_email) Registration.password_reset(nickname_or_email)
json_response(conn, :no_content, "") json_response(conn, :no_content, "")
end end

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.PasswordView do defmodule Pleroma.Web.OAuth.PasswordView do
use Pleroma.Web, :view use Pleroma.Web, :view
import Phoenix.HTML.Form import Phoenix.HTML.Form
alias Pleroma.Web.Gettext alias Pleroma.Web.Gettext

View file

@ -2,13 +2,13 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.Controller do defmodule Pleroma.Web.OAuth.TokenController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.TwitterAPI.TokenView alias Pleroma.Web.OAuth.TokenView
require Logger require Logger

View file

@ -2,12 +2,12 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.TokenView do defmodule Pleroma.Web.OAuth.TokenView do
use Pleroma.Web, :view use Pleroma.Web, :view
def render("index.json", %{tokens: tokens}) do def render("index.json", %{tokens: tokens}) do
tokens tokens
|> render_many(Pleroma.Web.TwitterAPI.TokenView, "show.json") |> render_many(Pleroma.Web.OAuth.TokenView, "show.json")
|> Enum.filter(&Enum.any?/1) |> Enum.filter(&Enum.any?/1)
end end

View file

@ -10,10 +10,8 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderController do
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
# Note: scope not present in Mastodon: read:bookmarks
plug(OAuthScopesPlug, %{scopes: ["read:bookmarks"]} when action == :index) plug(OAuthScopesPlug, %{scopes: ["read:bookmarks"]} when action == :index)
# Note: scope not present in Mastodon: write:bookmarks
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["write:bookmarks"]} when action in [:create, :update, :delete] %{scopes: ["write:bookmarks"]} when action in [:create, :update, :delete]

View file

@ -0,0 +1,52 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.PasswordController do
@moduledoc """
The module contains functions for password reset.
"""
use Pleroma.Web, :controller
require Logger
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
alias Pleroma.PasswordResetToken
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.Registration
plug(Pleroma.Web.Plugs.RateLimiter, [name: :request] when action == :request)
@doc "POST /auth/password"
def request(conn, params) do
nickname_or_email = params["email"] || params["nickname"]
Registration.password_reset(nickname_or_email)
json_response(conn, :no_content, "")
end
def reset(conn, %{"token" => token}) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
false <- PasswordResetToken.expired?(token),
%User{} = user <- User.get_cached_by_id(token.user_id) do
render(conn, "reset.html", %{
token: token,
user: user
})
else
_e -> render(conn, "invalid_token.html")
end
end
def do_reset(conn, %{"data" => data}) do
with {:ok, _} <- PasswordResetToken.reset_password(data["token"], data) do
render(conn, "reset_success.html")
else
_e -> render(conn, "reset_failed.html")
end
end
end

View file

@ -0,0 +1,59 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.TokenController do
use Pleroma.Web, :controller
alias Pleroma.User
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.PleromaAPI.TokenView
require Logger
plug(:skip_auth when action == :confirm_email)
plug(:skip_plug, OAuthScopesPlug when action in [:oauth_tokens, :revoke_token])
action_fallback(:errors)
def confirm_email(conn, %{"user_id" => uid, "token" => token}) do
with %User{} = user <- User.get_cached_by_id(uid),
true <- user.local and !user.is_confirmed and user.confirmation_token == token,
{:ok, _} <- User.confirm(user) do
redirect(conn, to: "/")
end
end
def oauth_tokens(%{assigns: %{user: user}} = conn, _params) do
with oauth_tokens <- Token.get_user_tokens(user) do
conn
|> put_view(TokenView)
|> render("index.json", %{tokens: oauth_tokens})
end
end
def revoke_token(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
Token.delete_user_token(user, id)
json_reply(conn, 201, "")
end
defp errors(conn, {:param_cast, _}) do
conn
|> put_status(400)
|> json("Invalid parameters")
end
defp errors(conn, _) do
conn
|> put_status(500)
|> json("Something went wrong")
end
defp json_reply(conn, status, json) do
conn
|> put_resp_content_type("application/json")
|> send_resp(status, json)
end
end

View file

@ -2,12 +2,11 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.UtilController do defmodule Pleroma.Web.PleromaAPI.UtilController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
require Logger require Logger
alias Pleroma.Activity
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.Emoji alias Pleroma.Emoji
alias Pleroma.Healthcheck alias Pleroma.Healthcheck
@ -17,19 +16,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
alias Pleroma.Web.Auth.WrapperAuthenticator, as: Authenticator alias Pleroma.Web.Auth.WrapperAuthenticator, as: Authenticator
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.WebFinger
plug( plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false)
Pleroma.Web.ApiSpec.CastAndValidate,
[replace_params: false]
when action != :remote_subscribe and action != :show_subscribe_form
)
plug(
Pleroma.Web.Plugs.FederatingPlug
when action == :remote_subscribe
when action == :show_subscribe_form
)
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
@ -54,125 +42,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
] ]
) )
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TwitterUtilOperation defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaUtilOperation
def show_subscribe_form(conn, %{"nickname" => nick}) do
with %User{} = user <- User.get_cached_by_nickname(nick),
avatar = User.avatar_url(user) do
conn
|> render("subscribe.html", %{nickname: nick, avatar: avatar, error: false})
else
_e ->
render(conn, "subscribe.html", %{
nickname: nick,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"remote follow error message - user not found",
"Could not find user"
)
})
end
end
def show_subscribe_form(conn, %{"status_id" => id}) do
with %Activity{} = activity <- Activity.get_by_id(id),
{:ok, ap_id} <- get_ap_id(activity),
%User{} = user <- User.get_cached_by_ap_id(activity.actor),
avatar = User.avatar_url(user) do
conn
|> render("status_interact.html", %{
status_link: ap_id,
status_id: id,
nickname: user.nickname,
avatar: avatar,
error: false
})
else
_e ->
render(conn, "status_interact.html", %{
status_id: id,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"status interact error message - status not found",
"Could not find status"
)
})
end
end
def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do
show_subscribe_form(conn, %{"nickname" => nick})
end
def remote_subscribe(conn, %{"status_id" => id, "profile" => _}) do
show_subscribe_form(conn, %{"status_id" => id})
end
def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profile}}) do
with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile),
%User{ap_id: ap_id} <- User.get_cached_by_nickname(nick) do
conn
|> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id))
else
_e ->
render(conn, "subscribe.html", %{
nickname: nick,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"remote follow error message - unknown error",
"Something went wrong."
)
})
end
end
def remote_subscribe(conn, %{"status" => %{"status_id" => id, "profile" => profile}}) do
with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile),
%Activity{} = activity <- Activity.get_by_id(id),
{:ok, ap_id} <- get_ap_id(activity) do
conn
|> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id))
else
_e ->
render(conn, "status_interact.html", %{
status_id: id,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"status interact error message - unknown error",
"Something went wrong."
)
})
end
end
def remote_interaction(
%{private: %{open_api_spex: %{body_params: %{ap_id: ap_id, profile: profile}}}} = conn,
_params
) do
with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile) do
conn
|> json(%{url: String.replace(template, "{uri}", ap_id)})
else
_e -> json(conn, %{error: "Couldn't find user"})
end
end
defp get_ap_id(activity) do
object = Pleroma.Object.normalize(activity, fetch: false)
case object do
%{data: %{"id" => ap_id}} -> {:ok, ap_id}
_ -> {:no_ap_id, nil}
end
end
def frontend_configurations(conn, _params) do def frontend_configurations(conn, _params) do
render(conn, "frontend_configurations.json") render(conn, "frontend_configurations.json")

View file

@ -9,11 +9,13 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do
alias Pleroma.Emoji alias Pleroma.Emoji
def render("show.json", %{folder: %BookmarkFolder{} = folder}) do def render("show.json", %{folder: %BookmarkFolder{} = folder}) do
{emoji, emoji_url} = get_emoji(folder.emoji)
%{ %{
id: folder.id |> to_string(), id: folder.id |> to_string(),
name: folder.name, name: folder.name,
emoji: folder.emoji, emoji: emoji,
emoji_url: get_emoji_url(folder.emoji) emoji_url: emoji_url
} }
end end
@ -21,20 +23,15 @@ defmodule Pleroma.Web.PleromaAPI.BookmarkFolderView do
render_many(folders, __MODULE__, "show.json", Map.delete(opts, :folders)) render_many(folders, __MODULE__, "show.json", Map.delete(opts, :folders))
end end
defp get_emoji_url(nil) do defp get_emoji(nil), do: {nil, nil}
nil
end
defp get_emoji_url(emoji) do defp get_emoji(emoji) do
if Emoji.unicode?(emoji) do if Emoji.unicode?(emoji) do
nil {emoji, nil}
else else
emoji = Emoji.get(emoji) case Emoji.get(emoji) do
nil -> {nil, nil}
if emoji != nil do emoji_data -> {emoji, Emoji.local_url(emoji_data.file)}
Emoji.local_url(emoji.file)
else
nil
end end
end end
end end

View file

@ -0,0 +1,13 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.UtilView do
use Pleroma.Web, :view
alias Pleroma.Config
def render("frontend_configurations.json", _) do
Config.get(:frontend_configurations, %{})
|> Enum.into(%{})
end
end

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Web.Preload.Providers.Instance do
alias Pleroma.Web.Nodeinfo.Nodeinfo alias Pleroma.Web.Nodeinfo.Nodeinfo
alias Pleroma.Web.Plugs.InstanceStatic alias Pleroma.Web.Plugs.InstanceStatic
alias Pleroma.Web.Preload.Providers.Provider alias Pleroma.Web.Preload.Providers.Provider
alias Pleroma.Web.TwitterAPI.UtilView alias Pleroma.Web.PleromaAPI.UtilView
@behaviour Provider @behaviour Provider
@instance_url "/api/v1/instance" @instance_url "/api/v1/instance"

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do defmodule Pleroma.Web.Registration do
import Pleroma.Web.Gettext import Pleroma.Web.Gettext
alias Pleroma.Emails.Mailer alias Pleroma.Emails.Mailer

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do defmodule Pleroma.Web.RemoteInteraction.RemoteInteractionController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
require Logger require Logger
@ -14,18 +14,27 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
alias Pleroma.Web.Auth.TOTPAuthenticator alias Pleroma.Web.Auth.TOTPAuthenticator
alias Pleroma.Web.Auth.WrapperAuthenticator alias Pleroma.Web.Auth.WrapperAuthenticator
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.WebFinger
@status_types ["Article", "Event", "Note", "Video", "Page", "Question"] @status_types ["Article", "Event", "Note", "Video", "Page", "Question"]
plug(
Pleroma.Web.ApiSpec.CastAndValidate,
[replace_params: false]
when action == :remote_interaction
)
plug(Pleroma.Web.Plugs.FederatingPlug) plug(Pleroma.Web.Plugs.FederatingPlug)
# Note: follower can submit the form (with password auth) not being signed in (having no token) # Note: follower can submit the form (with password auth) not being signed in (having no token)
plug( plug(
Pleroma.Web.Plugs.OAuthScopesPlug, Pleroma.Web.Plugs.OAuthScopesPlug,
%{fallback: :proceed_unauthenticated, scopes: ["follow", "write:follows"]} %{fallback: :proceed_unauthenticated, scopes: ["follow", "write:follows"]}
when action in [:do_follow] when action == :do_follow
) )
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.RemoteInteractionOperation
# GET /ostatus_subscribe # GET /ostatus_subscribe
# #
def follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do def follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
@ -125,7 +134,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
# #
def authorize_interaction(conn, %{"uri" => uri}) do def authorize_interaction(conn, %{"uri" => uri}) do
conn conn
|> redirect(to: Routes.remote_follow_path(conn, :follow, %{acct: uri})) |> redirect(to: Routes.remote_interaction_path(conn, :follow, %{acct: uri}))
end end
defp handle_follow_error(conn, {:mfa_token, followee, _} = _) do defp handle_follow_error(conn, {:mfa_token, followee, _} = _) do
@ -162,4 +171,122 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
Logger.debug("Remote follow failed with error #{inspect(error)}") Logger.debug("Remote follow failed with error #{inspect(error)}")
render(conn, "followed.html", %{error: "Something went wrong."}) render(conn, "followed.html", %{error: "Something went wrong."})
end end
def show_subscribe_form(conn, %{"nickname" => nick}) do
with %User{} = user <- User.get_cached_by_nickname(nick),
avatar = User.avatar_url(user) do
conn
|> render("subscribe.html", %{nickname: nick, avatar: avatar, error: false})
else
_e ->
render(conn, "subscribe.html", %{
nickname: nick,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"remote follow error message - user not found",
"Could not find user"
)
})
end
end
def show_subscribe_form(conn, %{"status_id" => id}) do
with %Activity{} = activity <- Activity.get_by_id(id),
{:ok, ap_id} <- get_ap_id(activity),
%User{} = user <- User.get_cached_by_ap_id(activity.actor),
avatar = User.avatar_url(user) do
conn
|> render("status_interact.html", %{
status_link: ap_id,
status_id: id,
nickname: user.nickname,
avatar: avatar,
error: false
})
else
_e ->
render(conn, "status_interact.html", %{
status_id: id,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"status interact error message - status not found",
"Could not find status"
)
})
end
end
def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do
show_subscribe_form(conn, %{"nickname" => nick})
end
def remote_subscribe(conn, %{"status_id" => id, "profile" => _}) do
show_subscribe_form(conn, %{"status_id" => id})
end
def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profile}}) do
with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile),
%User{ap_id: ap_id} <- User.get_cached_by_nickname(nick) do
conn
|> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id))
else
_e ->
render(conn, "subscribe.html", %{
nickname: nick,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"remote follow error message - unknown error",
"Something went wrong."
)
})
end
end
def remote_subscribe(conn, %{"status" => %{"status_id" => id, "profile" => profile}}) do
with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile),
%Activity{} = activity <- Activity.get_by_id(id),
{:ok, ap_id} <- get_ap_id(activity) do
conn
|> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id))
else
_e ->
render(conn, "status_interact.html", %{
status_id: id,
avatar: nil,
error:
Pleroma.Web.Gettext.dpgettext(
"static_pages",
"status interact error message - unknown error",
"Something went wrong."
)
})
end
end
def remote_interaction(
%{private: %{open_api_spex: %{body_params: %{ap_id: ap_id, profile: profile}}}} = conn,
_params
) do
with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile) do
conn
|> json(%{url: String.replace(template, "{uri}", ap_id)})
else
_e -> json(conn, %{error: "Couldn't find user"})
end
end
defp get_ap_id(activity) do
object = Pleroma.Object.normalize(activity, fetch: false)
case object do
%{data: %{"id" => ap_id}} -> {:ok, ap_id}
_ -> {:no_ap_id, nil}
end
end
end end

View file

@ -2,9 +2,11 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.RemoteFollowView do defmodule Pleroma.Web.RemoteInteraction.RemoteInteractionView do
use Pleroma.Web, :view use Pleroma.Web, :view
import Phoenix.HTML
import Phoenix.HTML.Form import Phoenix.HTML.Form
import Phoenix.HTML.Link
alias Pleroma.Web.Gettext alias Pleroma.Web.Gettext
def avatar_url(user) do def avatar_url(user) do

View file

@ -226,23 +226,28 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.StaticFEPlug) plug(Pleroma.Web.Plugs.StaticFEPlug)
end end
scope "/api/v1/pleroma", Pleroma.Web.TwitterAPI do scope "/api/v1/pleroma", Pleroma.Web.OAuth do
pipe_through(:pleroma_api) pipe_through(:pleroma_api)
get("/password_reset/:token", PasswordController, :reset, as: :reset_password) get("/password_reset/:token", PasswordController, :reset, as: :reset_password)
post("/password_reset", PasswordController, :do_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)
post("/remote_interaction", UtilController, :remote_interaction)
end end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
pipe_through(:pleroma_api) pipe_through(:pleroma_api)
get("/emoji", UtilController, :emoji)
get("/captcha", UtilController, :captcha)
get("/healthcheck", UtilController, :healthcheck)
get("/federation_status", InstancesController, :show) get("/federation_status", InstancesController, :show)
end end
scope "/api/v1/pleroma", Pleroma.Web.RemoteInteraction do
pipe_through(:pleroma_api)
post("/remote_interaction", RemoteInteractionController, :remote_interaction)
end
scope "/api/v1/pleroma", Pleroma.Web do scope "/api/v1/pleroma", Pleroma.Web do
pipe_through(:pleroma_api) pipe_through(:pleroma_api)
post("/uploader_callback/:upload_path", UploaderController, :callback) post("/uploader_callback/:upload_path", UploaderController, :callback)
@ -484,18 +489,18 @@ defmodule Pleroma.Web.Router do
end end
end end
scope "/", Pleroma.Web.TwitterAPI do scope "/", Pleroma.Web.RemoteInteraction do
pipe_through(:pleroma_html) pipe_through(:pleroma_html)
post("/main/ostatus", UtilController, :remote_subscribe) post("/main/ostatus", RemoteInteractionController, :remote_subscribe)
get("/main/ostatus", UtilController, :show_subscribe_form) get("/main/ostatus", RemoteInteractionController, :show_subscribe_form)
get("/ostatus_subscribe", RemoteFollowController, :follow) get("/ostatus_subscribe", RemoteInteractionController, :follow)
post("/ostatus_subscribe", RemoteFollowController, :do_follow) post("/ostatus_subscribe", RemoteInteractionController, :do_follow)
get("/authorize_interaction", RemoteFollowController, :authorize_interaction) get("/authorize_interaction", RemoteInteractionController, :authorize_interaction)
end end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do scope "/api/pleroma", Pleroma.Web.PleromaAPI do
pipe_through(:authenticated_api) pipe_through(:authenticated_api)
post("/change_email", UtilController, :change_email) post("/change_email", UtilController, :change_email)
@ -853,7 +858,7 @@ defmodule Pleroma.Web.Router do
scope "/api", Pleroma.Web do scope "/api", Pleroma.Web do
pipe_through(:config) pipe_through(:config)
get("/pleroma/frontend_configurations", TwitterAPI.UtilController, :frontend_configurations) get("/pleroma/frontend_configurations", PleromaAPI.UtilController, :frontend_configurations)
end end
scope "/api", Pleroma.Web do scope "/api", Pleroma.Web do
@ -861,7 +866,7 @@ defmodule Pleroma.Web.Router do
get( get(
"/account/confirm_email/:user_id/:token", "/account/confirm_email/:user_id/:token",
TwitterAPI.Controller, OAuth.TokenController,
:confirm_email, :confirm_email,
as: :confirm_email as: :confirm_email
) )
@ -873,11 +878,11 @@ defmodule Pleroma.Web.Router do
get("/openapi", OpenApiSpex.Plug.RenderSpec, []) get("/openapi", OpenApiSpex.Plug.RenderSpec, [])
end end
scope "/api", Pleroma.Web, as: :authenticated_twitter_api do scope "/api", Pleroma.Web, as: :authenticated_pleroma_api do
pipe_through(:authenticated_api) pipe_through(:authenticated_api)
get("/oauth_tokens", TwitterAPI.Controller, :oauth_tokens) get("/oauth_tokens", OAuth.TokenController, :oauth_tokens)
delete("/oauth_tokens/:id", TwitterAPI.Controller, :revoke_token) delete("/oauth_tokens/:id", OAuth.TokenController, :revoke_token)
end end
scope "/", Pleroma.Web do scope "/", Pleroma.Web do
@ -1026,7 +1031,7 @@ defmodule Pleroma.Web.Router do
scope "/", Pleroma.Web do scope "/", Pleroma.Web do
pipe_through(:pleroma_html) pipe_through(:pleroma_html)
post("/auth/password", TwitterAPI.PasswordController, :request) post("/auth/password", OAuth.PasswordController, :request)
end end
scope "/proxy/", Pleroma.Web do scope "/proxy/", Pleroma.Web do

View file

@ -4,7 +4,7 @@
<h2><%= Gettext.dpgettext("static_pages", "remote follow header", "Remote follow") %></h2> <h2><%= Gettext.dpgettext("static_pages", "remote follow header", "Remote follow") %></h2>
<img height="128" width="128" src="<%= avatar_url(@followee) %>"> <img height="128" width="128" src="<%= avatar_url(@followee) %>">
<p><%= @followee.nickname %></p> <p><%= @followee.nickname %></p>
<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "user"], fn f -> %> <%= form_for @conn, Routes.remote_interaction_path(@conn, :do_follow), [as: "user"], fn f -> %>
<%= hidden_input f, :id, value: @followee.id %> <%= hidden_input f, :id, value: @followee.id %>
<%= submit Gettext.dpgettext("static_pages", "remote follow authorization button", "Authorize") %> <%= submit Gettext.dpgettext("static_pages", "remote follow authorization button", "Authorize") %>
<% end %> <% end %>

View file

@ -4,7 +4,7 @@
<h2><%= Gettext.dpgettext("static_pages", "remote follow header, need login", "Log in to follow") %></h2> <h2><%= Gettext.dpgettext("static_pages", "remote follow header, need login", "Log in to follow") %></h2>
<p><%= @followee.nickname %></p> <p><%= @followee.nickname %></p>
<img height="128" width="128" src="<%= avatar_url(@followee) %>"> <img height="128" width="128" src="<%= avatar_url(@followee) %>">
<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "authorization"], fn f -> %> <%= form_for @conn, Routes.remote_interaction_path(@conn, :do_follow), [as: "authorization"], fn f -> %>
<%= text_input f, :name, placeholder: Gettext.dpgettext("static_pages", "placeholder text for username entry", "Username"), required: true, autocomplete: "username" %> <%= text_input f, :name, placeholder: Gettext.dpgettext("static_pages", "placeholder text for username entry", "Username"), required: true, autocomplete: "username" %>
<br> <br>
<%= password_input f, :password, placeholder: Gettext.dpgettext("static_pages", "placeholder text for password entry", "Password"), required: true, autocomplete: "password" %> <%= password_input f, :password, placeholder: Gettext.dpgettext("static_pages", "placeholder text for password entry", "Password"), required: true, autocomplete: "password" %>

View file

@ -4,7 +4,7 @@
<h2><%= Gettext.dpgettext("static_pages", "remote follow mfa header", "Two-factor authentication") %></h2> <h2><%= Gettext.dpgettext("static_pages", "remote follow mfa header", "Two-factor authentication") %></h2>
<p><%= @followee.nickname %></p> <p><%= @followee.nickname %></p>
<img height="128" width="128" src="<%= avatar_url(@followee) %>"> <img height="128" width="128" src="<%= avatar_url(@followee) %>">
<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "mfa"], fn f -> %> <%= form_for @conn, Routes.remote_interaction_path(@conn, :do_follow), [as: "mfa"], fn f -> %>
<%= text_input f, :code, placeholder: Gettext.dpgettext("static_pages", "placeholder text for auth code entry", "Authentication code"), required: true %> <%= text_input f, :code, placeholder: Gettext.dpgettext("static_pages", "placeholder text for auth code entry", "Authentication code"), required: true %>
<br> <br>
<%= hidden_input f, :id, value: @followee.id %> <%= hidden_input f, :id, value: @followee.id %>

View file

@ -2,7 +2,7 @@
<h2><%= Gettext.dpgettext("static_pages", "status interact error", "Error: %{error}", error: @error) %></h2> <h2><%= Gettext.dpgettext("static_pages", "status interact error", "Error: %{error}", error: @error) %></h2>
<% else %> <% else %>
<h2><%= raw Gettext.dpgettext("static_pages", "status interact header", "Interacting with %{nickname}'s %{status_link}", nickname: safe_to_string(html_escape(@nickname)), status_link: safe_to_string(link(Gettext.dpgettext("static_pages", "status interact header - status link text", "status"), to: @status_link))) %></h2> <h2><%= raw Gettext.dpgettext("static_pages", "status interact header", "Interacting with %{nickname}'s %{status_link}", nickname: safe_to_string(html_escape(@nickname)), status_link: safe_to_string(link(Gettext.dpgettext("static_pages", "status interact header - status link text", "status"), to: @status_link))) %></h2>
<%= form_for @conn, Routes.util_path(@conn, :remote_subscribe), [as: "status"], fn f -> %> <%= form_for @conn, Routes.remote_interaction_path(@conn, :remote_subscribe), [as: "status"], fn f -> %>
<%= hidden_input f, :status_id, value: @status_id %> <%= hidden_input f, :status_id, value: @status_id %>
<%= text_input f, :profile, placeholder: Gettext.dpgettext("static_pages", "placeholder text for account id", "Your account ID, e.g. lain@quitter.se") %> <%= text_input f, :profile, placeholder: Gettext.dpgettext("static_pages", "placeholder text for account id", "Your account ID, e.g. lain@quitter.se") %>
<%= submit Gettext.dpgettext("static_pages", "status interact authorization button", "Interact") %> <%= submit Gettext.dpgettext("static_pages", "status interact authorization button", "Interact") %>

View file

@ -2,7 +2,7 @@
<h2><%= Gettext.dpgettext("static_pages", "remote follow error", "Error: %{error}", error: @error) %></h2> <h2><%= Gettext.dpgettext("static_pages", "remote follow error", "Error: %{error}", error: @error) %></h2>
<% else %> <% else %>
<h2><%= Gettext.dpgettext("static_pages", "remote follow header", "Remotely follow %{nickname}", nickname: @nickname) %></h2> <h2><%= Gettext.dpgettext("static_pages", "remote follow header", "Remotely follow %{nickname}", nickname: @nickname) %></h2>
<%= form_for @conn, Routes.util_path(@conn, :remote_subscribe), [as: "user"], fn f -> %> <%= form_for @conn, Routes.remote_interaction_path(@conn, :remote_subscribe), [as: "user"], fn f -> %>
<%= hidden_input f, :nickname, value: @nickname %> <%= hidden_input f, :nickname, value: @nickname %>
<%= text_input f, :profile, placeholder: Gettext.dpgettext("static_pages", "placeholder text for account id", "Your account ID, e.g. lain@quitter.se") %> <%= text_input f, :profile, placeholder: Gettext.dpgettext("static_pages", "placeholder text for account id", "Your account ID, e.g. lain@quitter.se") %>
<%= submit Gettext.dpgettext("static_pages", "remote follow authorization button for following with a remote account", "Follow") %> <%= submit Gettext.dpgettext("static_pages", "remote follow authorization button for following with a remote account", "Follow") %>

View file

@ -2,7 +2,7 @@
<h1><%= link instance_name(), to: "/" %></h1> <h1><%= link instance_name(), to: "/" %></h1>
<h3> <h3>
<form class="pull-right collapse" method="POST" action="<%= Helpers.util_path(@conn, :remote_subscribe) %>"> <form class="pull-right collapse" method="POST" action="<%= Helpers.remote_interaction_path(@conn, :remote_subscribe) %>">
<input type="hidden" name="nickname" value="<%= @user.nickname %>"> <input type="hidden" name="nickname" value="<%= @user.nickname %>">
<input type="hidden" name="profile" value=""> <input type="hidden" name="profile" value="">
<button type="submit" class="collapse"><%= Gettext.dpgettext("static_pages", "static fe profile page remote follow button", "Remote follow") %></button> <button type="submit" class="collapse"><%= Gettext.dpgettext("static_pages", "static fe profile page remote follow button", "Remote follow") %></button>

View file

@ -1,31 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.UtilView do
use Pleroma.Web, :view
import Phoenix.HTML
import Phoenix.HTML.Form
import Phoenix.HTML.Link
alias Pleroma.Config
alias Pleroma.Web.Endpoint
alias Pleroma.Web.Gettext
def status_net_config(instance) do
"""
<config>
<site>
<name>#{Keyword.get(instance, :name)}</name>
<site>#{Endpoint.url()}</site>
<textlimit>#{Keyword.get(instance, :limit)}</textlimit>
<closed>#{!Keyword.get(instance, :registrations_open)}</closed>
</site>
</config>
"""
end
def render("frontend_configurations.json", _) do
Config.get(:frontend_configurations, %{})
|> Enum.into(%{})
end
end

View file

@ -15,7 +15,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicyTest do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#nsfw hey"}) {:ok, activity} = CommonAPI.post(user, %{status: "#nsfw hey"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert modified["object"]["sensitive"] assert modified["object"]["sensitive"]
end end
@ -94,7 +94,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicyTest do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe hey"}) {:ok, activity} = CommonAPI.post(user, %{status: "#cofe hey"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
refute modified["object"]["sensitive"] refute modified["object"]["sensitive"]
end end

View file

@ -67,7 +67,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
{:ok, edit} = Pleroma.Web.CommonAPI.update(activity, user, %{status: "edited :blank:"}) {:ok, edit} = Pleroma.Web.CommonAPI.update(activity, user, %{status: "edited :blank:"})
{:ok, %{"object" => external_rep}} = {:ok, %{"object" => external_rep}} =
Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data) Pleroma.Web.ActivityPub.Transmogrifier.prepare_activity(edit.data)
%{external_rep: external_rep} %{external_rep: external_rep}
end end

View file

@ -133,7 +133,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
user = insert(:user) user = insert(:user)
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"}) {:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"})
{:ok, edit} = Pleroma.Web.CommonAPI.update(activity, user, %{status: "edited :blank:"}) {:ok, edit} = Pleroma.Web.CommonAPI.update(activity, user, %{status: "edited :blank:"})
{:ok, external_rep} = Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data) {:ok, external_rep} = Pleroma.Web.ActivityPub.Transmogrifier.prepare_activity(edit.data)
%{external_rep: external_rep} %{external_rep: external_rep}
end end

View file

@ -259,7 +259,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
) )
end end
test "Publishes with the new actor if prepare_outgoing changes the actor." do test "Publishes with the new actor if prepare_activity changes the actor." do
mock(fn mock(fn
%{method: :post, url: "https://domain.com/users/nick1/inbox", body: body} -> %{method: :post, url: "https://domain.com/users/nick1/inbox", body: body} ->
{:ok, %Tesla.Env{status: 200, body: body}} {:ok, %Tesla.Env{status: 200, body: body}}
@ -281,7 +281,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
) )
Pleroma.Web.ActivityPub.TransmogrifierMock Pleroma.Web.ActivityPub.TransmogrifierMock
|> Mox.expect(:prepare_outgoing, fn data -> |> Mox.expect(:prepare_activity, fn data ->
{:ok, Map.put(data, "actor", replaced_actor.ap_id)} {:ok, Map.put(data, "actor", replaced_actor.ap_id)}
end) end)

View file

@ -72,7 +72,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnswerHandlingTest do
|> Kernel.put_in(["object", "to"], user.ap_id) |> Kernel.put_in(["object", "to"], user.ap_id)
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data) {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data) {:ok, data} = Transmogrifier.prepare_activity(activity.data)
assert data["object"]["type"] == "Note" assert data["object"]["type"] == "Note"
end end

View file

@ -508,7 +508,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
{:ok, activity} = Transmogrifier.handle_incoming(message) {:ok, activity} = Transmogrifier.handle_incoming(message)
{:ok, _} = Transmogrifier.prepare_outgoing(activity.data) {:ok, _} = Transmogrifier.prepare_activity(activity.data)
end end
test "successfully reserializes a message with AS2 objects in IR" do test "successfully reserializes a message with AS2 objects in IR" do
@ -537,7 +537,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
{:ok, activity} = Transmogrifier.handle_incoming(message) {:ok, activity} = Transmogrifier.handle_incoming(message)
{:ok, _} = Transmogrifier.prepare_outgoing(activity.data) {:ok, _} = Transmogrifier.prepare_activity(activity.data)
end end
end end

View file

@ -433,7 +433,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest 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_activity(announce_activity.data)
assert modified["object"]["content"] == "hey" assert modified["object"]["content"] == "hey"
assert modified["object"]["actor"] == modified["object"]["attributedTo"] assert modified["object"]["actor"] == modified["object"]["attributedTo"]
@ -448,7 +448,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
with_mock Pleroma.Notification, with_mock Pleroma.Notification,
get_notified_from_activity: fn _, _ -> [] end do get_notified_from_activity: fn _, _ -> [] end do
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
object = modified["object"] object = modified["object"]
@ -474,7 +474,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"}) {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert modified["@context"] == Utils.make_json_ld_header()["@context"] assert modified["@context"] == Utils.make_json_ld_header()["@context"]
@ -485,7 +485,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"}) {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert modified["object"]["actor"] == modified["object"]["attributedTo"] assert modified["object"]["actor"] == modified["object"]["attributedTo"]
end end
@ -501,7 +501,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
"name" => "#2hu" "name" => "#2hu"
} }
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert modified["object"]["tag"] == [expected_tag] assert modified["object"]["tag"] == [expected_tag]
end end
@ -524,7 +524,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
url: "https://pleroma.social" url: "https://pleroma.social"
} == activity.object.data["generator"] } == activity.object.data["generator"]
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert length(modified["object"]["tag"]) == 2 assert length(modified["object"]["tag"]) == 2
@ -541,7 +541,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
test "it strips internal fields of article" do test "it strips internal fields of article" do
activity = insert(:article_activity) activity = insert(:article_activity)
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert length(modified["object"]["tag"]) == 2 assert length(modified["object"]["tag"]) == 2
@ -558,13 +558,13 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, activity} = CommonAPI.post(user, %{status: "2hu :moominmamma:"}) {:ok, activity} = CommonAPI.post(user, %{status: "2hu :moominmamma:"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert modified["directMessage"] == false assert modified["directMessage"] == false
{:ok, activity} = CommonAPI.post(user, %{status: "@#{other_user.nickname} :moominmamma:"}) {:ok, activity} = CommonAPI.post(user, %{status: "@#{other_user.nickname} :moominmamma:"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert modified["directMessage"] == false assert modified["directMessage"] == false
@ -574,7 +574,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
visibility: "direct" visibility: "direct"
}) })
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert modified["directMessage"] == true assert modified["directMessage"] == true
end end
@ -585,7 +585,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"}) {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert is_nil(modified["bcc"]) assert is_nil(modified["bcc"])
end end
@ -594,7 +594,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
listen_activity = insert(:listen) listen_activity = insert(:listen)
# This has an inlined object as in ObjectView # This has an inlined object as in ObjectView
{:ok, modified} = Transmogrifier.prepare_outgoing(listen_activity.data) {:ok, modified} = Transmogrifier.prepare_activity(listen_activity.data)
assert modified["type"] == "Listen" assert modified["type"] == "Listen"
@ -610,7 +610,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
object_type = activity.object.data["type"] object_type = activity.object.data["type"]
# This does not have an inlined object # This does not have an inlined object
{:ok, modified2} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified2} = Transmogrifier.prepare_activity(activity.data)
assert match?( assert match?(
%{ %{
@ -640,7 +640,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"}) {:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"})
{:ok, prepared} = Transmogrifier.prepare_outgoing(activity.data) {:ok, prepared} = Transmogrifier.prepare_activity(activity.data)
assert length(prepared["object"]["tag"]) == 1 assert length(prepared["object"]["tag"]) == 1
@ -655,7 +655,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"}) {:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"})
{:ok, update} = CommonAPI.update(activity, user, %{status: "mew mew :blank:"}) {:ok, update} = CommonAPI.update(activity, user, %{status: "mew mew :blank:"})
{:ok, prepared} = Transmogrifier.prepare_outgoing(update.data) {:ok, prepared} = Transmogrifier.prepare_activity(update.data)
assert %{ assert %{
"content" => "mew mew :blank:", "content" => "mew mew :blank:",
@ -689,7 +689,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
user_update_changeset: changeset user_update_changeset: changeset
) )
assert {:ok, prepared} = Transmogrifier.prepare_outgoing(activity.data) assert {:ok, prepared} = Transmogrifier.prepare_activity(activity.data)
assert prepared["type"] == "Update" assert prepared["type"] == "Update"
assert prepared["@context"] assert prepared["@context"]
assert prepared["object"]["type"] == user.actor_type assert prepared["object"]["type"] == user.actor_type
@ -704,7 +704,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, %Activity{} = block_activity} = CommonAPI.block(blocked, blocker) {:ok, %Activity{} = block_activity} = CommonAPI.block(blocked, blocker)
{:ok, %Activity{} = undo_activity} = CommonAPI.unblock(blocked, blocker) {:ok, %Activity{} = undo_activity} = CommonAPI.unblock(blocked, blocker)
{:ok, data} = Transmogrifier.prepare_outgoing(undo_activity.data) {:ok, data} = Transmogrifier.prepare_activity(undo_activity.data)
block_ap_id = block_activity.data["id"] block_ap_id = block_activity.data["id"]
assert is_binary(block_ap_id) assert is_binary(block_ap_id)
@ -738,7 +738,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert is_binary(note_ap_id) assert is_binary(note_ap_id)
{:ok, react_activity} = CommonAPI.react_with_emoji(note_activity.id, user, "🐈") {:ok, react_activity} = CommonAPI.react_with_emoji(note_activity.id, user, "🐈")
{:ok, data} = Transmogrifier.prepare_outgoing(react_activity.data) {:ok, data} = Transmogrifier.prepare_activity(react_activity.data)
assert match?( assert match?(
%{ %{
@ -764,7 +764,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
note_activity = insert(:note_activity) note_activity = insert(:note_activity)
{:ok, react_activity} = CommonAPI.react_with_emoji(note_activity.id, user, ":dinosaur:") {:ok, react_activity} = CommonAPI.react_with_emoji(note_activity.id, user, ":dinosaur:")
{:ok, data} = Transmogrifier.prepare_outgoing(react_activity.data) {:ok, data} = Transmogrifier.prepare_activity(react_activity.data)
assert length(data["tag"]) == 1 assert length(data["tag"]) == 1
@ -781,7 +781,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"}) {:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"})
{:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quoted_status_id: quoted_post.id}) {:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quoted_status_id: quoted_post.id})
{:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data) {:ok, modified} = Transmogrifier.prepare_activity(quote_post.data)
%{data: %{"id" => quote_id}} = Object.normalize(quoted_post) %{data: %{"id" => quote_id}} = Object.normalize(quoted_post)
@ -793,7 +793,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "Cześć", language: "pl"}) {:ok, activity} = CommonAPI.post(user, %{status: "Cześć", language: "pl"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.object.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.object.data)
assert [_, _, %{"@language" => "pl"}] = modified["@context"] assert [_, _, %{"@language" => "pl"}] = modified["@context"]
end end
@ -802,7 +802,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "Cześć", language: "pl"}) {:ok, activity} = CommonAPI.post(user, %{status: "Cześć", language: "pl"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) {:ok, modified} = Transmogrifier.prepare_activity(activity.data)
assert [_, _, %{"@language" => "pl"}] = modified["@context"] assert [_, _, %{"@language" => "pl"}] = modified["@context"]
end end
@ -825,7 +825,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
content: content content: content
}) })
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data) {:ok, data} = Transmogrifier.prepare_activity(activity.data)
expected_data = expected_data =
activity.data activity.data
@ -859,7 +859,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
clear_config([:activitypub, :anonymize_reporter], true) clear_config([:activitypub, :anonymize_reporter], true)
clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname) clear_config([:activitypub, :anonymize_reporter_local_nickname], placeholder.nickname)
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data) {:ok, data} = Transmogrifier.prepare_activity(activity.data)
expected_data = expected_data =
activity.data activity.data

View file

@ -2096,7 +2096,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
result = result =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> get("api/v1/blocks") |> get("/api/v1/blocks")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
assert [ assert [

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do defmodule Pleroma.Web.OAuth.PasswordControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase
alias Pleroma.Config alias Pleroma.Config

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.ControllerTest do defmodule Pleroma.Web.OAuth.TokenControllerTest do
use Pleroma.Web.ConnCase, async: true use Pleroma.Web.ConnCase, async: true
alias Pleroma.Repo alias Pleroma.Repo

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do defmodule Pleroma.Web.PleromaAPI.UtilControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase
use Oban.Testing, repo: Pleroma.Repo use Oban.Testing, repo: Pleroma.Repo
@ -182,153 +182,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
end end
end end
describe "POST /main/ostatus - remote_subscribe/2" do
setup do: clear_config([:instance, :federating], true)
test "renders subscribe form", %{conn: conn} do
user = insert(:user)
response =
conn
|> post("/main/ostatus", %{"nickname" => user.nickname, "profile" => ""})
|> response(:ok)
refute response =~ "Could not find user"
assert response =~ "Remotely follow #{user.nickname}"
end
test "renders subscribe form with error when user not found", %{conn: conn} do
response =
conn
|> post("/main/ostatus", %{"nickname" => "nickname", "profile" => ""})
|> response(:ok)
assert response =~ "Could not find user"
refute response =~ "Remotely follow"
end
test "it redirect to webfinger url", %{conn: conn} do
user = insert(:user)
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
conn =
conn
|> post("/main/ostatus", %{
"user" => %{"nickname" => user.nickname, "profile" => user2.ap_id}
})
assert redirected_to(conn) ==
"https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}"
end
test "it renders form with error when user not found", %{conn: conn} do
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
response =
conn
|> post("/main/ostatus", %{"user" => %{"nickname" => "jimm", "profile" => user2.ap_id}})
|> response(:ok)
assert response =~ "Something went wrong."
end
end
describe "POST /main/ostatus - remote_subscribe/2 - with statuses" do
setup do: clear_config([:instance, :federating], true)
test "renders subscribe form", %{conn: conn} do
user = insert(:user)
status = insert(:note_activity, %{user: user})
status_id = status.id
assert is_binary(status_id)
response =
conn
|> post("/main/ostatus", %{"status_id" => status_id, "profile" => ""})
|> response(:ok)
refute response =~ "Could not find status"
assert response =~ "Interacting with"
end
test "renders subscribe form with error when status not found", %{conn: conn} do
response =
conn
|> post("/main/ostatus", %{"status_id" => "somerandomid", "profile" => ""})
|> response(:ok)
assert response =~ "Could not find status"
refute response =~ "Interacting with"
end
test "it redirect to webfinger url", %{conn: conn} do
user = insert(:user)
status = insert(:note_activity, %{user: user})
status_id = status.id
status_ap_id = status.data["object"]
assert is_binary(status_id)
assert is_binary(status_ap_id)
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
conn =
conn
|> post("/main/ostatus", %{
"status" => %{"status_id" => status_id, "profile" => user2.ap_id}
})
assert redirected_to(conn) ==
"https://social.heldscal.la/main/ostatussub?profile=#{status_ap_id}"
end
test "it renders form with error when status not found", %{conn: conn} do
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
response =
conn
|> post("/main/ostatus", %{
"status" => %{"status_id" => "somerandomid", "profile" => user2.ap_id}
})
|> response(:ok)
assert response =~ "Something went wrong."
end
end
describe "GET /main/ostatus - show_subscribe_form/2" do
setup do: clear_config([:instance, :federating], true)
test "it works with users", %{conn: conn} do
user = insert(:user)
response =
conn
|> get("/main/ostatus", %{"nickname" => user.nickname})
|> response(:ok)
refute response =~ "Could not find user"
assert response =~ "Remotely follow #{user.nickname}"
end
test "it works with statuses", %{conn: conn} do
user = insert(:user)
status = insert(:note_activity, %{user: user})
status_id = status.id
assert is_binary(status_id)
response =
conn
|> get("/main/ostatus", %{"status_id" => status_id})
|> response(:ok)
refute response =~ "Could not find status"
assert response =~ "Interacting with"
end
end
test "it returns new captcha", %{conn: conn} do test "it returns new captcha", %{conn: conn} do
with_mock Pleroma.Captcha, with_mock Pleroma.Captcha,
new: fn -> "test_captcha" end do new: fn -> "test_captcha" end do

View file

@ -2,14 +2,14 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do defmodule Pleroma.Web.RegistrationTest do
use Pleroma.DataCase use Pleroma.DataCase
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers alias Pleroma.Tests.ObanHelpers
alias Pleroma.User alias Pleroma.User
alias Pleroma.UserInviteToken alias Pleroma.UserInviteToken
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.Registration
setup_all do setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -25,7 +25,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:confirm => "bear" :confirm => "bear"
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
assert user == User.get_cached_by_nickname("lain") assert user == User.get_cached_by_nickname("lain")
end end
@ -40,7 +40,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:confirm => "bear" :confirm => "bear"
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
assert user == User.get_cached_by_nickname("lain") assert user == User.get_cached_by_nickname("lain")
end end
@ -57,7 +57,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:confirm => "bear" :confirm => "bear"
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
ObanHelpers.perform_all() ObanHelpers.perform_all()
refute user.is_confirmed refute user.is_confirmed
@ -89,7 +89,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:reason => "I love anime" :reason => "I love anime"
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
ObanHelpers.perform_all() ObanHelpers.perform_all()
refute user.is_approved refute user.is_approved
@ -125,7 +125,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:confirm => "bear" :confirm => "bear"
} }
{:ok, user1} = TwitterAPI.register_user(data1) {:ok, user1} = Registration.register_user(data1)
data2 = %{ data2 = %{
:username => "lain", :username => "lain",
@ -136,7 +136,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:confirm => "bear" :confirm => "bear"
} }
{:ok, user2} = TwitterAPI.register_user(data2) {:ok, user2} = Registration.register_user(data2)
expected_text = expected_text =
~s(<span class="h-card"><a class="u-url mention" data-user="#{user1.id}" href="#{user1.ap_id}" rel="ugc">@<span>john</span></a></span> test) ~s(<span class="h-card"><a class="u-url mention" data-user="#{user1.id}" href="#{user1.ap_id}" rel="ugc">@<span>john</span></a></span> test)
@ -160,7 +160,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
assert user == User.get_cached_by_nickname("vinny") assert user == User.get_cached_by_nickname("vinny")
@ -179,7 +179,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => "DudeLetMeInImAFairy" :token => "DudeLetMeInImAFairy"
} }
{:error, msg} = TwitterAPI.register_user(data) {:error, msg} = Registration.register_user(data)
assert msg == "Invalid token" assert msg == "Invalid token"
refute User.get_cached_by_nickname("GrimReaper") refute User.get_cached_by_nickname("GrimReaper")
@ -199,7 +199,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:error, msg} = TwitterAPI.register_user(data) {:error, msg} = Registration.register_user(data)
assert msg == "Expired token" assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper") refute User.get_cached_by_nickname("GrimReaper")
@ -221,7 +221,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
check_fn = fn invite -> check_fn = fn invite ->
data = Map.put(data, :token, invite.token) data = Map.put(data, :token, invite.token)
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
assert user == User.get_cached_by_nickname("vinny") assert user == User.get_cached_by_nickname("vinny")
end end
@ -254,7 +254,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
data = Map.put(data, "token", invite.token) data = Map.put(data, "token", invite.token)
{:error, msg} = TwitterAPI.register_user(data) {:error, msg} = Registration.register_user(data)
assert msg == "Expired token" assert msg == "Expired token"
refute User.get_cached_by_nickname("vinny") refute User.get_cached_by_nickname("vinny")
@ -282,7 +282,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
assert user == User.get_cached_by_nickname("vinny") assert user == User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token) invite = Repo.get_by(UserInviteToken, token: invite.token)
@ -298,7 +298,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:error, msg} = TwitterAPI.register_user(data) {:error, msg} = Registration.register_user(data)
assert msg == "Expired token" assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper") refute User.get_cached_by_nickname("GrimReaper")
@ -321,7 +321,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
assert user == User.get_cached_by_nickname("vinny") assert user == User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token) invite = Repo.get_by(UserInviteToken, token: invite.token)
@ -343,7 +343,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:ok, user} = TwitterAPI.register_user(data) {:ok, user} = Registration.register_user(data)
assert user == User.get_cached_by_nickname("vinny") assert user == User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token) invite = Repo.get_by(UserInviteToken, token: invite.token)
@ -359,7 +359,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:error, msg} = TwitterAPI.register_user(data) {:error, msg} = Registration.register_user(data)
assert msg == "Expired token" assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper") refute User.get_cached_by_nickname("GrimReaper")
@ -379,7 +379,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:error, msg} = TwitterAPI.register_user(data) {:error, msg} = Registration.register_user(data)
assert msg == "Expired token" assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper") refute User.get_cached_by_nickname("GrimReaper")
@ -401,7 +401,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:token => invite.token :token => invite.token
} }
{:error, msg} = TwitterAPI.register_user(data) {:error, msg} = Registration.register_user(data)
assert msg == "Expired token" assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper") refute User.get_cached_by_nickname("GrimReaper")
@ -416,7 +416,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
:bio => "close the world." :bio => "close the world."
} }
{:error, error} = TwitterAPI.register_user(data) {:error, error} = Registration.register_user(data)
assert is_binary(error) assert is_binary(error)
refute User.get_cached_by_nickname("lain") refute User.get_cached_by_nickname("lain")

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do defmodule Pleroma.Web.RemoteInteraction.RemoteInteractionControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase
alias Pleroma.MFA alias Pleroma.MFA
@ -16,6 +16,11 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
import Mox import Mox
import Pleroma.Factory import Pleroma.Factory
setup do
Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
setup_all do: clear_config([:instance, :federating], true) setup_all do: clear_config([:instance, :federating], true)
setup do: clear_config([:user, :deny_follow_blocked]) setup do: clear_config([:user, :deny_follow_blocked])
@ -49,7 +54,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
assert conn assert conn
|> get( |> get(
remote_follow_path(conn, :follow, %{ remote_interaction_path(conn, :follow, %{
acct: "https://mastodon.social/users/emelie/statuses/101849165031453009" acct: "https://mastodon.social/users/emelie/statuses/101849165031453009"
}) })
) )
@ -78,7 +83,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"})) |> get(remote_interaction_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}))
|> html_response(200) |> html_response(200)
assert response =~ "Log in to follow" assert response =~ "Log in to follow"
@ -109,7 +114,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"})) |> get(remote_interaction_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}))
|> html_response(200) |> html_response(200)
assert response =~ "Remote follow" assert response =~ "Remote follow"
@ -130,7 +135,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
conn conn
|> assign(:user, user) |> assign(:user, user)
|> get( |> get(
remote_follow_path(conn, :follow, %{ remote_interaction_path(conn, :follow, %{
acct: "https://mastodon.social/users/not_found" acct: "https://mastodon.social/users/not_found"
}) })
) )
@ -152,7 +157,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
conn conn
|> assign(:user, user) |> assign(:user, user)
|> assign(:token, read_token) |> assign(:token, read_token)
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) |> post(remote_interaction_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
|> response(200) |> response(200)
assert response =~ "Error following account" assert response =~ "Error following account"
@ -167,7 +172,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
conn conn
|> assign(:user, user) |> assign(:user, user)
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"])) |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) |> post(remote_interaction_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
assert redirected_to(conn) == "/users/#{user2.id}" assert redirected_to(conn) == "/users/#{user2.id}"
end end
@ -179,7 +184,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) |> post(remote_interaction_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
|> response(200) |> response(200)
assert response =~ "Error following account" assert response =~ "Error following account"
@ -195,7 +200,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) |> post(remote_interaction_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
|> response(200) |> response(200)
assert response =~ "Error following account" assert response =~ "Error following account"
@ -207,7 +212,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => "jimm"}}) |> post(remote_interaction_path(conn, :do_follow), %{"user" => %{"id" => "jimm"}})
|> response(200) |> response(200)
assert response =~ "Error following account" assert response =~ "Error following account"
@ -222,7 +227,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
conn conn
|> assign(:user, refresh_record(user)) |> assign(:user, refresh_record(user))
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"])) |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) |> post(remote_interaction_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
assert redirected_to(conn) == "/users/#{user2.id}" assert redirected_to(conn) == "/users/#{user2.id}"
end end
@ -244,7 +249,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> post(remote_follow_path(conn, :do_follow), %{ |> post(remote_interaction_path(conn, :do_follow), %{
"authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id} "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
}) })
|> response(200) |> response(200)
@ -272,7 +277,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> post(remote_follow_path(conn, :do_follow), %{ |> post(remote_interaction_path(conn, :do_follow), %{
"authorization" => %{"name" => user.nickname, "password" => "test1", "id" => user2.id} "authorization" => %{"name" => user.nickname, "password" => "test1", "id" => user2.id}
}) })
|> response(200) |> response(200)
@ -300,7 +305,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
conn = conn =
conn conn
|> post( |> post(
remote_follow_path(conn, :do_follow), remote_interaction_path(conn, :do_follow),
%{ %{
"mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id} "mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id}
} }
@ -329,7 +334,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> post( |> post(
remote_follow_path(conn, :do_follow), remote_interaction_path(conn, :do_follow),
%{ %{
"mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id} "mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id}
} }
@ -348,7 +353,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
conn = conn =
conn conn
|> post(remote_follow_path(conn, :do_follow), %{ |> post(remote_interaction_path(conn, :do_follow), %{
"authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id} "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
}) })
@ -361,7 +366,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> post(remote_follow_path(conn, :do_follow), %{ |> post(remote_interaction_path(conn, :do_follow), %{
"authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"} "authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"}
}) })
|> response(200) |> response(200)
@ -374,7 +379,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> post(remote_follow_path(conn, :do_follow), %{ |> post(remote_interaction_path(conn, :do_follow), %{
"authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id} "authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id}
}) })
|> response(200) |> response(200)
@ -388,7 +393,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> post(remote_follow_path(conn, :do_follow), %{ |> post(remote_interaction_path(conn, :do_follow), %{
"authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id} "authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id}
}) })
|> response(200) |> response(200)
@ -404,7 +409,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
response = response =
conn conn
|> post(remote_follow_path(conn, :do_follow), %{ |> post(remote_interaction_path(conn, :do_follow), %{
"authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id} "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
}) })
|> response(200) |> response(200)
@ -423,7 +428,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
avatar: %{"url" => [%{"href" => "https://remote.org/avatar.png"}]} avatar: %{"url" => [%{"href" => "https://remote.org/avatar.png"}]}
}) })
avatar_url = Pleroma.Web.TwitterAPI.RemoteFollowView.avatar_url(user) avatar_url = Pleroma.Web.RemoteInteraction.RemoteInteractionView.avatar_url(user)
assert avatar_url == "https://remote.org/avatar.png" assert avatar_url == "https://remote.org/avatar.png"
end end
@ -440,7 +445,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
avatar: %{"url" => [%{"href" => "https://remote.org/avatar.png"}]} avatar: %{"url" => [%{"href" => "https://remote.org/avatar.png"}]}
}) })
avatar_url = Pleroma.Web.TwitterAPI.RemoteFollowView.avatar_url(user) avatar_url = Pleroma.Web.RemoteInteraction.RemoteInteractionView.avatar_url(user)
url = Pleroma.Web.Endpoint.url() url = Pleroma.Web.Endpoint.url()
assert String.starts_with?(avatar_url, url) assert String.starts_with?(avatar_url, url)
@ -455,7 +460,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
avatar: %{"url" => [%{"href" => "#{Pleroma.Web.Endpoint.url()}/localuser/avatar.png"}]} avatar: %{"url" => [%{"href" => "#{Pleroma.Web.Endpoint.url()}/localuser/avatar.png"}]}
}) })
avatar_url = Pleroma.Web.TwitterAPI.RemoteFollowView.avatar_url(user) avatar_url = Pleroma.Web.RemoteInteraction.RemoteInteractionView.avatar_url(user)
assert avatar_url == "#{Pleroma.Web.Endpoint.url()}/localuser/avatar.png" assert avatar_url == "#{Pleroma.Web.Endpoint.url()}/localuser/avatar.png"
end end
@ -485,13 +490,160 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
conn = conn =
conn conn
|> get( |> get(
remote_follow_path(conn, :authorize_interaction, %{ remote_interaction_path(conn, :authorize_interaction, %{
uri: "https://mastodon.social/users/emelie" uri: "https://mastodon.social/users/emelie"
}) })
) )
assert redirected_to(conn) == assert redirected_to(conn) ==
remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}) remote_interaction_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"})
end
end
describe "POST /main/ostatus - remote_subscribe/2" do
setup do: clear_config([:instance, :federating], true)
test "renders subscribe form", %{conn: conn} do
user = insert(:user)
response =
conn
|> post("/main/ostatus", %{"nickname" => user.nickname, "profile" => ""})
|> response(:ok)
refute response =~ "Could not find user"
assert response =~ "Remotely follow #{user.nickname}"
end
test "renders subscribe form with error when user not found", %{conn: conn} do
response =
conn
|> post("/main/ostatus", %{"nickname" => "nickname", "profile" => ""})
|> response(:ok)
assert response =~ "Could not find user"
refute response =~ "Remotely follow"
end
test "it redirect to webfinger url", %{conn: conn} do
user = insert(:user)
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
conn =
conn
|> post("/main/ostatus", %{
"user" => %{"nickname" => user.nickname, "profile" => user2.ap_id}
})
assert redirected_to(conn) ==
"https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}"
end
test "it renders form with error when user not found", %{conn: conn} do
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
response =
conn
|> post("/main/ostatus", %{"user" => %{"nickname" => "jimm", "profile" => user2.ap_id}})
|> response(:ok)
assert response =~ "Something went wrong."
end
end
describe "POST /main/ostatus - remote_subscribe/2 - with statuses" do
setup do: clear_config([:instance, :federating], true)
test "renders subscribe form", %{conn: conn} do
user = insert(:user)
status = insert(:note_activity, %{user: user})
status_id = status.id
assert is_binary(status_id)
response =
conn
|> post("/main/ostatus", %{"status_id" => status_id, "profile" => ""})
|> response(:ok)
refute response =~ "Could not find status"
assert response =~ "Interacting with"
end
test "renders subscribe form with error when status not found", %{conn: conn} do
response =
conn
|> post("/main/ostatus", %{"status_id" => "somerandomid", "profile" => ""})
|> response(:ok)
assert response =~ "Could not find status"
refute response =~ "Interacting with"
end
test "it redirect to webfinger url", %{conn: conn} do
user = insert(:user)
status = insert(:note_activity, %{user: user})
status_id = status.id
status_ap_id = status.data["object"]
assert is_binary(status_id)
assert is_binary(status_ap_id)
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
conn =
conn
|> post("/main/ostatus", %{
"status" => %{"status_id" => status_id, "profile" => user2.ap_id}
})
assert redirected_to(conn) ==
"https://social.heldscal.la/main/ostatussub?profile=#{status_ap_id}"
end
test "it renders form with error when status not found", %{conn: conn} do
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
response =
conn
|> post("/main/ostatus", %{
"status" => %{"status_id" => "somerandomid", "profile" => user2.ap_id}
})
|> response(:ok)
assert response =~ "Something went wrong."
end
end
describe "GET /main/ostatus - show_subscribe_form/2" do
setup do: clear_config([:instance, :federating], true)
test "it works with users", %{conn: conn} do
user = insert(:user)
response =
conn
|> get("/main/ostatus", %{"nickname" => user.nickname})
|> response(:ok)
refute response =~ "Could not find user"
assert response =~ "Remotely follow #{user.nickname}"
end
test "it works with statuses", %{conn: conn} do
user = insert(:user)
status = insert(:note_activity, %{user: user})
status_id = status.id
assert is_binary(status_id)
response =
conn
|> get("/main/ostatus", %{"status_id" => status_id})
|> response(:ok)
refute response =~ "Could not find status"
assert response =~ "Interacting with"
end end
end end
end end