#
# You can give explicit globs or simply directories.
# In the latter case `**/*.{ex,exs}` will be used.
- included: ["lib/", "src/", "web/", "apps/"],
+ included: ["lib/", "src/", "web/", "apps/", "test/"],
excluded: [~r"/_build/", ~r"/deps/"]
},
#
allow_direct: false
config :pleroma, :mrf_hellthread,
- delist_threshold: 5,
- reject_threshold: 10
+ delist_threshold: 10,
+ reject_threshold: 20
config :pleroma, :mrf_simple,
media_removal: [],
# Strip the beginning @ off if there is a query
query = String.trim_leading(query, "@")
- if resolve, do: User.get_or_fetch_by_nickname(query)
+ if resolve, do: get_or_fetch(query)
fts_results = do_search(fts_search_subquery(query), for_user)
if object = Object.get_cached_by_ap_id(id) do
{:ok, object}
else
- Logger.info("Fetching #{id} via AP")
-
with {:ok, data} <- fetch_and_contain_remote_object_from_id(id),
nil <- Object.normalize(data),
params <- %{
end
def fetch_and_contain_remote_object_from_id(id) do
- Logger.info("Fetching #{id} via AP")
+ Logger.info("Fetching object #{id} via AP")
with true <- String.starts_with?(id, "http"),
{:ok, %{body: body, status: code}} when code in 200..299 <-
alias Pleroma.User
@behaviour Pleroma.Web.ActivityPub.MRF
- defp delist_message(message) do
+ defp delist_message(message, threshold) when threshold > 0 do
follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address
- message
- |> Map.put("to", [follower_collection])
- |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"])
+ follower_collection? = Enum.member?(message["to"] ++ message["cc"], follower_collection)
+
+ message =
+ case recipients = get_recipient_count(message) do
+ {:public, _}
+ when follower_collection? and recipients > threshold ->
+ message
+ |> Map.put("to", [follower_collection])
+ |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"])
+
+ {:public, _} when recipients > threshold ->
+ message
+ |> Map.put("to", [])
+ |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"])
+
+ _ ->
+ message
+ end
+
+ {:ok, message}
+ end
+
+ defp delist_message(message, _threshold), do: {:ok, message}
+
+ defp reject_message(message, threshold) when threshold > 0 do
+ with {_, recipients} <- get_recipient_count(message) do
+ if recipients > threshold do
+ {:reject, nil}
+ else
+ {:ok, message}
+ end
+ end
+ end
+
+ defp reject_message(message, _threshold), do: {:ok, message}
+
+ defp get_recipient_count(message) do
+ recipients = (message["to"] || []) ++ (message["cc"] || [])
+ follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address
+
+ if Enum.member?(recipients, "https://www.w3.org/ns/activitystreams#Public") do
+ recipients =
+ recipients
+ |> List.delete("https://www.w3.org/ns/activitystreams#Public")
+ |> List.delete(follower_collection)
+
+ {:public, length(recipients)}
+ else
+ recipients =
+ recipients
+ |> List.delete(follower_collection)
+
+ {:not_public, length(recipients)}
+ end
end
@impl true
def filter(%{"type" => "Create"} = message) do
- delist_threshold = Pleroma.Config.get([:mrf_hellthread, :delist_threshold])
-
reject_threshold =
Pleroma.Config.get(
[:mrf_hellthread, :reject_threshold],
Pleroma.Config.get([:mrf_hellthread, :threshold])
)
- recipients = (message["to"] || []) ++ (message["cc"] || [])
-
- cond do
- length(recipients) > reject_threshold and reject_threshold > 0 ->
- {:reject, nil}
-
- length(recipients) > delist_threshold and delist_threshold > 0 ->
- if Enum.member?(message["to"], "https://www.w3.org/ns/activitystreams#Public") or
- Enum.member?(message["cc"], "https://www.w3.org/ns/activitystreams#Public") do
- {:ok, delist_message(message)}
- else
- {:ok, message}
- end
+ delist_threshold = Pleroma.Config.get([:mrf_hellthread, :delist_threshold])
- true ->
- {:ok, message}
+ with {:ok, message} <- reject_message(message, reject_threshold),
+ {:ok, message} <- delist_message(message, delist_threshold) do
+ {:ok, message}
+ else
+ _e -> {:reject, nil}
end
end
if object = Object.normalize(id), do: {:ok, object}, else: nil
end
- def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) do
+ def set_reply_to_uri(%{"inReplyTo" => inReplyTo} = object) when is_binary(inReplyTo) do
with false <- String.starts_with?(inReplyTo, "http"),
{:ok, %{data: replied_to_object}} <- get_obj_helper(inReplyTo) do
Map.put(object, "inReplyTo", replied_to_object["external_url"] || inReplyTo)
def add_hashtags(object) do
tags =
(object["tag"] || [])
- |> Enum.map(fn tag ->
- %{
- "href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}",
- "name" => "##{tag}",
- "type" => "Hashtag"
- }
+ |> Enum.map(fn
+ # Expand internal representation tags into AS2 tags.
+ tag when is_binary(tag) ->
+ %{
+ "href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}",
+ "name" => "##{tag}",
+ "type" => "Hashtag"
+ }
+
+ # Do not process tags which are already AS2 tag objects.
+ tag when is_map(tag) ->
+ tag
end)
object
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.Router.Helpers
+ alias Pleroma.Web.Endpoint
import Ecto.Query
+ def render("endpoints.json", %{user: %User{nickname: nil, local: true} = _user}) do
+ %{"sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)}
+ end
+
+ def render("endpoints.json", %{user: %User{local: true} = _user}) do
+ %{
+ "oauthAuthorizationEndpoint" => Helpers.o_auth_url(Endpoint, :authorize),
+ "oauthRegistrationEndpoint" => Helpers.mastodon_api_url(Endpoint, :create_app),
+ "oauthTokenEndpoint" => Helpers.o_auth_url(Endpoint, :token_exchange),
+ "sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)
+ }
+ end
+
+ def render("endpoints.json", _), do: %{}
+
# the instance itself is not a Person, but instead an Application
def render("user.json", %{user: %{nickname: nil} = user}) do
{:ok, user} = WebFinger.ensure_keys_present(user)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
+ endpoints = render("endpoints.json", %{user: user})
+
%{
"id" => user.ap_id,
"type" => "Application",
"owner" => user.ap_id,
"publicKeyPem" => public_key
},
- "endpoints" => %{
- "sharedInbox" => "#{Pleroma.Web.Endpoint.url()}/inbox"
- }
+ "endpoints" => endpoints
}
|> Map.merge(Utils.make_json_ld_header())
end
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
+ endpoints = render("endpoints.json", %{user: user})
+
%{
"id" => user.ap_id,
"type" => "Person",
"owner" => user.ap_id,
"publicKeyPem" => public_key
},
- "endpoints" => %{
- "sharedInbox" => "#{Pleroma.Web.Endpoint.url()}/inbox"
- },
+ "endpoints" => endpoints,
"icon" => %{
"type" => "Image",
"url" => User.avatar_url(user)
query = from(user in query, select: [:ap_id])
following = Repo.all(query)
- collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows)
+ total =
+ if !user.info.hide_follows do
+ length(following)
+ else
+ 0
+ end
+
+ collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows, total)
|> Map.merge(Utils.make_json_ld_header())
end
query = from(user in query, select: [:ap_id])
following = Repo.all(query)
+ total =
+ if !user.info.hide_follows do
+ length(following)
+ else
+ 0
+ end
+
%{
"id" => "#{user.ap_id}/following",
"type" => "OrderedCollection",
- "totalItems" => length(following),
+ "totalItems" => total,
"first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows)
}
|> Map.merge(Utils.make_json_ld_header())
query = from(user in query, select: [:ap_id])
followers = Repo.all(query)
- collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers)
+ total =
+ if !user.info.hide_followers do
+ length(followers)
+ else
+ 0
+ end
+
+ collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers, total)
|> Map.merge(Utils.make_json_ld_header())
end
query = from(user in query, select: [:ap_id])
followers = Repo.all(query)
+ total =
+ if !user.info.hide_followers do
+ length(followers)
+ else
+ 0
+ end
+
%{
"id" => "#{user.ap_id}/followers",
"type" => "OrderedCollection",
- "totalItems" => length(followers),
- "first" => collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers)
+ "totalItems" => total,
+ "first" =>
+ collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers, total)
}
|> Map.merge(Utils.make_json_ld_header())
end
def render("outbox.json", %{user: user, max_id: max_qid}) do
- # XXX: technically note_count is wrong for this, but it's better than nothing
- info = User.user_info(user)
-
params = %{
"limit" => "10"
}
"id" => "#{iri}?max_id=#{max_id}",
"type" => "OrderedCollectionPage",
"partOf" => iri,
- "totalItems" => info.note_count,
"orderedItems" => collection,
"next" => "#{iri}?max_id=#{min_id}"
}
%{
"id" => iri,
"type" => "OrderedCollection",
- "totalItems" => info.note_count,
"first" => page
}
|> Map.merge(Utils.make_json_ld_header())
"id" => "#{iri}?max_id=#{max_id}",
"type" => "OrderedCollectionPage",
"partOf" => iri,
- "totalItems" => -1,
"orderedItems" => collection,
"next" => "#{iri}?max_id=#{min_id}"
}
%{
"id" => iri,
"type" => "OrderedCollection",
- "totalItems" => -1,
"first" => page
}
|> Map.merge(Utils.make_json_ld_header())
else
secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]
+ # Must preserve `%2F` for compatibility with S3 (https://git.pleroma.social/pleroma/pleroma/issues/580)
+ replacement = get_replacement(url, ":2F:")
+
# The URL is url-decoded and encoded again to ensure it is correctly encoded and not twice.
base64 =
url
+ |> String.replace("%2F", replacement)
|> URI.decode()
|> URI.encode()
+ |> String.replace(replacement, "%2F")
|> Base.url_encode64(@base64_opts)
sig = :crypto.hmac(:sha, secret, base64)
|> Enum.filter(fn value -> value end)
|> Path.join()
end
+
+ defp get_replacement(url, replacement) do
+ if String.contains?(url, replacement) do
+ get_replacement(url, replacement <> replacement)
+ else
+ replacement
+ end
+ end
end
scope "/", Pleroma.Web.ActivityPub do
pipe_through(:activitypub)
- post("/users/:nickname/inbox", ActivityPubController, :inbox)
post("/inbox", ActivityPubController, :inbox)
+ post("/users/:nickname/inbox", ActivityPubController, :inbox)
end
scope "/.well-known", Pleroma.Web do
"value": "schema:value",
"sensitive": "as:sensitive",
"litepub": "http://litepub.social/ns#",
- "directMessage": "litepub:directMessage"
+ "directMessage": "litepub:directMessage",
+ "oauthRegistrationEndpoint": {
+ "@id": "litepub:oauthRegistrationEndpoint",
+ "@type": "@id"
+ }
}
]
}
{subs, text} = Formatter.add_user_links({[], text}, mentions)
- assert length(subs) == 0
+ assert Enum.empty?(subs)
Enum.each(subs, fn {uuid, _} -> assert String.contains?(text, uuid) end)
expected_text = "@a hi"
assert String.starts_with?(encoded, Pleroma.Config.get([:media_proxy, :base_url]))
end
+
+ # https://git.pleroma.social/pleroma/pleroma/issues/580
+ test "encoding S3 links (must preserve `%2F`)" do
+ url =
+ "https://s3.amazonaws.com/example/test.png?X-Amz-Credential=your-access-key-id%2F20130721%2Fus-east-1%2Fs3%2Faws4_request"
+
+ encoded = url(url)
+ assert decode_result(encoded) == url
+ end
end
describe "when disabled" do
use Pleroma.DataCase
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.CommonAPI
- alias Pleroma.{User, Notification}
+ alias Pleroma.User
+ alias Pleroma.Notification
alias Pleroma.Web.ActivityPub.Transmogrifier
import Pleroma.Factory
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
{:ok, _} = CommonAPI.delete(activity.id, user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
end
test "liking an activity results in 1 notification, then 0 if the activity is unliked" do
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
{:ok, _, _, _} = CommonAPI.unfavorite(activity.id, other_user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
end
test "repeating an activity results in 1 notification, then 0 if the activity is deleted" do
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
{:ok, _} = CommonAPI.delete(activity.id, user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
end
test "repeating an activity results in 1 notification, then 0 if the activity is unrepeated" do
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
{:ok, _, _} = CommonAPI.unrepeat(activity.id, other_user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
end
test "liking an activity which is already deleted does not generate a notification" do
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:error, _} = CommonAPI.favorite(activity.id, other_user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
end
test "repeating an activity which is already deleted does not generate a notification" do
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
{:error, _} = CommonAPI.repeat(activity.id, other_user)
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
end
test "replying to a deleted post without tagging does not generate a notification" do
"in_reply_to_status_id" => activity.id
})
- assert length(Notification.for_user(user)) == 0
+ assert Enum.empty?(Notification.for_user(user))
end
end
end
defmodule Pleroma.ObjectTest do
use Pleroma.DataCase
import Pleroma.Factory
- alias Pleroma.{Repo, Object}
+ alias Pleroma.Repo
+ alias Pleroma.Object
test "returns an object by it's AP id" do
object = insert(:note)
defmodule Pleroma.Builders.UserBuilder do
- alias Pleroma.{User, Repo}
+ alias Pleroma.User
+ alias Pleroma.Repo
def build(data \\ %{}) do
user = %User{
defmodule Mix.Tasks.Pleroma.RelayTest do
alias Pleroma.Activity
- alias Pleroma.Web.ActivityPub.{ActivityPub, Relay, Utils}
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.User
use Pleroma.DataCase
assert message =~ "Successfully unsubscribed"
user = User.get_by_nickname(user.nickname)
- assert length(user.following) == 0
+ assert Enum.empty?(user.following)
assert user.info.deactivated
end
defmodule Pleroma.UserTest do
alias Pleroma.Builders.UserBuilder
- alias Pleroma.{User, Repo, Activity}
+ alias Pleroma.Activity
+ alias Pleroma.Repo
+ alias Pleroma.User
alias Pleroma.Web.CommonAPI
use Pleroma.DataCase
assert [] == User.search(query)
end)
end
+
+ test "works with URIs" do
+ results = User.search("http://mastodon.example.org/users/admin", true)
+ result = results |> List.first()
+
+ user = User.get_by_ap_id("http://mastodon.example.org/users/admin")
+
+ assert length(results) == 1
+ assert user == result |> Map.put(:search_rank, nil)
+ end
end
test "auth_active?/1 works correctly" do
defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
- alias Pleroma.Web.ActivityPub.{UserView, ObjectView}
- alias Pleroma.{Object, Repo, Activity, User, Instances}
+ alias Pleroma.Web.ActivityPub.UserView
+ alias Pleroma.Web.ActivityPub.ObjectView
+ alias Pleroma.Object
+ alias Pleroma.Repo
+ alias Pleroma.Activity
+ alias Pleroma.User
+ alias Pleroma.Instances
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|> json_response(200)
assert result["first"]["orderedItems"] == []
- assert result["totalItems"] == 1
+ assert result["totalItems"] == 0
end
test "it works for more than 10 users", %{conn: conn} do
|> json_response(200)
assert result["first"]["orderedItems"] == []
- assert result["totalItems"] == 1
+ assert result["totalItems"] == 0
end
test "it works for more than 10 users", %{conn: conn} do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
- alias Pleroma.{Activity, Object, User, Instances}
+ alias Pleroma.Activity
+ alias Pleroma.Object
+ alias Pleroma.User
+ alias Pleroma.Instances
alias Pleroma.Builders.ActivityBuilder
import Pleroma.Factory
--- /dev/null
+# Pleroma: A lightweight social networking server
+# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
+ use Pleroma.DataCase
+ import Pleroma.Factory
+
+ import Pleroma.Web.ActivityPub.MRF.HellthreadPolicy
+
+ describe "hellthread filter tests" do
+ setup do
+ user = insert(:user)
+
+ message = %{
+ "actor" => user.ap_id,
+ "cc" => [user.follower_address],
+ "type" => "Create",
+ "to" => [
+ "https://www.w3.org/ns/activitystreams#Public",
+ "https://instace.tld/users/user1",
+ "https://instace.tld/users/user2",
+ "https://instace.tld/users/user3"
+ ]
+ }
+
+ [user: user, message: message]
+ end
+
+ test "reject test", %{message: message} do
+ Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 2})
+
+ {:reject, nil} = filter(message)
+ end
+
+ test "delist test", %{user: user, message: message} do
+ Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 2, reject_threshold: 0})
+
+ {:ok, message} = filter(message)
+ assert user.follower_address in message["to"]
+ assert "https://www.w3.org/ns/activitystreams#Public" in message["cc"]
+ end
+
+ test "excludes follower collection and public URI from threshold count", %{message: message} do
+ Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 3})
+
+ {:ok, _} = filter(message)
+ end
+ end
+end
)
end
end
+
+ describe "reserialization" do
+ test "successfully reserializes a message with inReplyTo == nil" do
+ user = insert(:user)
+
+ message = %{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "cc" => [],
+ "type" => "Create",
+ "object" => %{
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "cc" => [],
+ "type" => "Note",
+ "content" => "Hi",
+ "inReplyTo" => nil,
+ "attributedTo" => user.ap_id
+ },
+ "actor" => user.ap_id
+ }
+
+ {:ok, activity} = Transmogrifier.handle_incoming(message)
+
+ {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
+ end
+
+ test "successfully reserializes a message with AS2 objects in IR" do
+ user = insert(:user)
+
+ message = %{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "cc" => [],
+ "type" => "Create",
+ "object" => %{
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "cc" => [],
+ "type" => "Note",
+ "content" => "Hi",
+ "inReplyTo" => nil,
+ "attributedTo" => user.ap_id,
+ "tag" => [
+ %{"name" => "#2hu", "href" => "http://example.com/2hu", "type" => "Hashtag"},
+ %{"name" => "Bob", "href" => "http://example.com/bob", "type" => "Mention"}
+ ]
+ },
+ "actor" => user.ap_id
+ }
+
+ {:ok, activity} = Transmogrifier.handle_incoming(message)
+
+ {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
+ end
+ end
end
assert String.contains?(result["publicKey"]["publicKeyPem"], "BEGIN PUBLIC KEY")
end
+
+ describe "endpoints" do
+ test "local users have a usable endpoints structure" do
+ user = insert(:user)
+ {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
+
+ result = UserView.render("user.json", %{user: user})
+
+ assert result["id"] == user.ap_id
+
+ %{
+ "sharedInbox" => _,
+ "oauthAuthorizationEndpoint" => _,
+ "oauthRegistrationEndpoint" => _,
+ "oauthTokenEndpoint" => _
+ } = result["endpoints"]
+ end
+
+ test "remote users have an empty endpoints structure" do
+ user = insert(:user, local: false)
+ {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
+
+ result = UserView.render("user.json", %{user: user})
+
+ assert result["id"] == user.ap_id
+ assert result["endpoints"] == %{}
+ end
+
+ test "instance users do not expose oAuth endpoints" do
+ user = insert(:user, nickname: nil, local: true)
+ {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
+
+ result = UserView.render("user.json", %{user: user})
+
+ refute result["endpoints"]["oauthAuthorizationEndpoint"]
+ refute result["endpoints"]["oauthRegistrationEndpoint"]
+ refute result["endpoints"]["oauthTokenEndpoint"]
+ end
+ end
end
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
use Pleroma.Web.ConnCase
- alias Pleroma.{Repo, User}
+ alias Pleroma.Repo
+ alias Pleroma.User
import Pleroma.Factory
describe "/api/pleroma/admin/user" do
defmodule Pleroma.Web.CommonAPI.UtilsTest do
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.Endpoint
- alias Pleroma.Builders.{UserBuilder}
+ alias Pleroma.Builders.UserBuilder
use Pleroma.DataCase
test "it adds attachment links to a given text and attachment set" do
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.FederatorTest do
- alias Pleroma.Web.{CommonAPI, Federator}
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.Federator
alias Pleroma.Instances
use Pleroma.DataCase
import Pleroma.Factory
use Pleroma.Web.ConnCase
alias Pleroma.Web.TwitterAPI.TwitterAPI
- alias Pleroma.{Repo, User, Object, Activity, Notification}
- alias Pleroma.Web.{OStatus, CommonAPI}
+ alias Pleroma.Repo
+ alias Pleroma.User
+ alias Pleroma.Object
+ alias Pleroma.Activity
+ alias Pleroma.Notification
+ alias Pleroma.Web.OStatus
+ alias Pleroma.Web.CommonAPI
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.MastodonAPI.FilterView
alias Ecto.Changeset
|> assign(:user, user)
|> get("/api/v1/timelines/home")
- assert length(json_response(conn, 200)) == 0
+ assert Enum.empty?(json_response(conn, 200))
{:ok, user} = User.follow(user, following)
defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
use Pleroma.DataCase
- alias Pleroma.Web.MastodonAPI.{StatusView, AccountView}
+ alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.User
alias Pleroma.Web.OStatus
alias Pleroma.Web.CommonAPI
defmodule Pleroma.Web.OAuth.AuthorizationTest do
use Pleroma.DataCase
- alias Pleroma.Web.OAuth.{Authorization, App}
+ alias Pleroma.Web.OAuth.Authorization
+ alias Pleroma.Web.OAuth.App
import Pleroma.Factory
test "create an authorization token for a valid app" do
import Pleroma.Factory
alias Pleroma.Repo
- alias Pleroma.Web.OAuth.{Authorization, Token}
+ alias Pleroma.Web.OAuth.Authorization
+ alias Pleroma.Web.OAuth.Token
test "redirects with oauth authorization" do
user = insert(:user)
defmodule Pleroma.Web.OAuth.TokenTest do
use Pleroma.DataCase
- alias Pleroma.Web.OAuth.{App, Token, Authorization}
+ alias Pleroma.Web.OAuth.App
+ alias Pleroma.Web.OAuth.Authorization
+ alias Pleroma.Web.OAuth.Token
alias Pleroma.Repo
import Pleroma.Factory
use Pleroma.DataCase
alias Pleroma.Web.OStatus.ActivityRepresenter
- alias Pleroma.{User, Activity, Object}
+ alias Pleroma.Activity
+ alias Pleroma.User
+ alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.OStatus
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.User
- alias Pleroma.Web.OStatus.{FeedRepresenter, UserRepresenter, ActivityRepresenter}
+ alias Pleroma.Web.OStatus.ActivityRepresenter
+ alias Pleroma.Web.OStatus.FeedRepresenter
+ alias Pleroma.Web.OStatus.UserRepresenter
alias Pleroma.Web.OStatus
test "returns a feed of the last 20 items of the user" do
import Pleroma.Factory
import Tesla.Mock
- alias Pleroma.{Repo, Activity, Object}
+ alias Pleroma.Repo
+ alias Pleroma.Activity
+ alias Pleroma.Object
alias Pleroma.Web.OStatus
setup do
defmodule Pleroma.Web.OStatus.OStatusControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
- alias Pleroma.{User, Repo, Object}
+ alias Pleroma.User
+ alias Pleroma.Repo
+ alias Pleroma.Object
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OStatus.ActivityRepresenter
use Pleroma.DataCase
alias Pleroma.Web.OStatus
alias Pleroma.Web.XML
- alias Pleroma.{Object, Repo, User, Activity, Instances}
+ alias Pleroma.Object
+ alias Pleroma.Repo
+ alias Pleroma.User
+ alias Pleroma.Activity
+ alias Pleroma.Instances
import Pleroma.Factory
import ExUnit.CaptureLog
defmodule Pleroma.Web.Salmon.SalmonTest do
use Pleroma.DataCase
alias Pleroma.Web.Salmon
- alias Pleroma.{Repo, Activity, User}
+ alias Pleroma.Activity
+ alias Pleroma.Repo
+ alias Pleroma.User
import Pleroma.Factory
@magickey "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwQhh-1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
use Pleroma.DataCase
- alias Pleroma.{User, Activity, Object}
- alias Pleroma.Web.TwitterAPI.Representers.{ActivityRepresenter, ObjectRepresenter}
+ alias Pleroma.User
+ alias Pleroma.Activity
+ alias Pleroma.Object
+ alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
+ alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.TwitterAPI.UserView
import Pleroma.Factory
defmodule Pleroma.Web.TwitterAPI.ControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
- alias Pleroma.Builders.{ActivityBuilder, UserBuilder}
- alias Pleroma.{Repo, Activity, User, Object, Notification}
+ alias Pleroma.Builders.ActivityBuilder
+ alias Pleroma.Builders.UserBuilder
+ alias Pleroma.Repo
+ alias Pleroma.Activity
+ alias Pleroma.User
+ alias Pleroma.Object
+ alias Pleroma.Notification
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.TwitterAPI.UserView
alias Pleroma.Web.TwitterAPI.NotificationView
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
- alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView}
- alias Pleroma.{Activity, User, Object, Repo, UserInviteToken}
+ alias Pleroma.Web.TwitterAPI.TwitterAPI
+ alias Pleroma.Web.TwitterAPI.UserView
+ alias Pleroma.Activity
+ alias Pleroma.User
+ alias Pleroma.Object
+ alias Pleroma.Repo
+ alias Pleroma.UserInviteToken
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.TwitterAPI.ActivityView
defmodule Pleroma.Web.TwitterAPI.NotificationViewTest do
use Pleroma.DataCase
- alias Pleroma.{User, Notification}
+ alias Pleroma.User
+ alias Pleroma.Notification
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.NotificationView
alias Pleroma.Web.TwitterAPI.UserView
use Pleroma.Web.ConnCase
import Pleroma.Factory
alias Pleroma.Web.Websub.WebsubClientSubscription
- alias Pleroma.{Repo, Activity}
+ alias Pleroma.Activity
+ alias Pleroma.Repo
alias Pleroma.Web.Websub
test "websub subscription request", %{conn: conn} do
assert response(conn, 500) == "Error"
- assert length(Repo.all(Activity)) == 0
+ assert Enum.empty?(Repo.all(Activity))
end
end
end
defmodule Pleroma.Web.WebsubTest do
use Pleroma.DataCase
alias Pleroma.Web.Websub
- alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription}
+ alias Pleroma.Web.Websub.WebsubServerSubscription
+ alias Pleroma.Web.Websub.WebsubClientSubscription
import Pleroma.Factory
alias Pleroma.Web.Router.Helpers
import Tesla.Mock