commit: 7dffaef4799b0e867e91e19b76567c0e1a19bb43
parent 6bf85440b373c9b2fa1e8e7184dcf87518600306
Author: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Tue, 23 Jun 2020 18:16:47 +0300
tests consistency
Diffstat:
294 files changed, 3268 insertions(+), 3267 deletions(-)
diff --git a/test/fixtures/modules/runtime_module.ex b/test/fixtures/modules/runtime_module.ex
@@ -2,7 +2,7 @@
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
-defmodule RuntimeModule do
+defmodule Fixtures.Modules.RuntimeModule do
@moduledoc """
This is a dummy module to test custom runtime modules.
"""
diff --git a/test/activity/ir/topics_test.exs b/test/pleroma/activity/ir/topics_test.exs
diff --git a/test/activity_test.exs b/test/pleroma/activity_test.exs
diff --git a/test/bbs/handler_test.exs b/test/pleroma/bbs/handler_test.exs
diff --git a/test/bookmark_test.exs b/test/pleroma/bookmark_test.exs
diff --git a/test/captcha_test.exs b/test/pleroma/captcha_test.exs
diff --git a/test/chat/message_reference_test.exs b/test/pleroma/chat/message_reference_test.exs
diff --git a/test/chat_test.exs b/test/pleroma/chat_test.exs
diff --git a/test/config/deprecation_warnings_test.exs b/test/pleroma/config/deprecation_warnings_test.exs
diff --git a/test/config/holder_test.exs b/test/pleroma/config/holder_test.exs
diff --git a/test/config/loader_test.exs b/test/pleroma/config/loader_test.exs
diff --git a/test/config/transfer_task_test.exs b/test/pleroma/config/transfer_task_test.exs
diff --git a/test/config/config_db_test.exs b/test/pleroma/config_db_test.exs
diff --git a/test/config_test.exs b/test/pleroma/config_test.exs
diff --git a/test/conversation/participation_test.exs b/test/pleroma/conversation/participation_test.exs
diff --git a/test/conversation_test.exs b/test/pleroma/conversation_test.exs
diff --git a/test/docs/generator_test.exs b/test/pleroma/docs/generator_test.exs
diff --git a/test/earmark_renderer_test.exs b/test/pleroma/earmark_renderer_test.exs
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/date_time_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/date_time_test.exs
@@ -0,0 +1,36 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.DateTimeTest do
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime
+ use Pleroma.DataCase
+
+ test "it validates an xsd:Datetime" do
+ valid_strings = [
+ "2004-04-12T13:20:00",
+ "2004-04-12T13:20:15.5",
+ "2004-04-12T13:20:00-05:00",
+ "2004-04-12T13:20:00Z"
+ ]
+
+ invalid_strings = [
+ "2004-04-12T13:00",
+ "2004-04-1213:20:00",
+ "99-04-12T13:00",
+ "2004-04-12"
+ ]
+
+ assert {:ok, "2004-04-01T12:00:00Z"} == DateTime.cast("2004-04-01T12:00:00Z")
+
+ Enum.each(valid_strings, fn date_time ->
+ result = DateTime.cast(date_time)
+ assert {:ok, _} = result
+ end)
+
+ Enum.each(invalid_strings, fn date_time ->
+ result = DateTime.cast(date_time)
+ assert :error == result
+ end)
+ end
+end
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/object_id_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/object_id_test.exs
@@ -0,0 +1,41 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectIDTest do
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID
+ use Pleroma.DataCase
+
+ @uris [
+ "http://lain.com/users/lain",
+ "http://lain.com",
+ "https://lain.com/object/1"
+ ]
+
+ @non_uris [
+ "https://",
+ "rin",
+ 1,
+ :x,
+ %{"1" => 2}
+ ]
+
+ test "it accepts http uris" do
+ Enum.each(@uris, fn uri ->
+ assert {:ok, uri} == ObjectID.cast(uri)
+ end)
+ end
+
+ test "it accepts an object with a nested uri id" do
+ Enum.each(@uris, fn uri ->
+ assert {:ok, uri} == ObjectID.cast(%{"id" => uri})
+ end)
+ end
+
+ test "it rejects non-uri strings" do
+ Enum.each(@non_uris, fn non_uri ->
+ assert :error == ObjectID.cast(non_uri)
+ assert :error == ObjectID.cast(%{"id" => non_uri})
+ end)
+ end
+end
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs
@@ -0,0 +1,31 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.RecipientsTest do
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients
+ use Pleroma.DataCase
+
+ test "it asserts that all elements of the list are object ids" do
+ list = ["https://lain.com/users/lain", "invalid"]
+
+ assert :error == Recipients.cast(list)
+ end
+
+ test "it works with a list" do
+ list = ["https://lain.com/users/lain"]
+ assert {:ok, list} == Recipients.cast(list)
+ end
+
+ test "it works with a list with whole objects" do
+ list = ["https://lain.com/users/lain", %{"id" => "https://gensokyo.2hu/users/raymoo"}]
+ resulting_list = ["https://gensokyo.2hu/users/raymoo", "https://lain.com/users/lain"]
+ assert {:ok, resulting_list} == Recipients.cast(list)
+ end
+
+ test "it turns a single string into a list" do
+ recipient = "https://lain.com/users/lain"
+
+ assert {:ok, [recipient]} == Recipients.cast(recipient)
+ end
+end
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/safe_text_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/safe_text_test.exs
@@ -0,0 +1,30 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.SafeTextTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.SafeText
+
+ test "it lets normal text go through" do
+ text = "hey how are you"
+ assert {:ok, text} == SafeText.cast(text)
+ end
+
+ test "it removes html tags from text" do
+ text = "hey look xss <script>alert('foo')</script>"
+ assert {:ok, "hey look xss alert('foo')"} == SafeText.cast(text)
+ end
+
+ test "it keeps basic html tags" do
+ text = "hey <a href='http://gensokyo.2hu'>look</a> xss <script>alert('foo')</script>"
+
+ assert {:ok, "hey <a href=\"http://gensokyo.2hu\">look</a> xss alert('foo')"} ==
+ SafeText.cast(text)
+ end
+
+ test "errors for non-text" do
+ assert :error == SafeText.cast(1)
+ end
+end
diff --git a/test/emails/admin_email_test.exs b/test/pleroma/emails/admin_email_test.exs
diff --git a/test/emails/mailer_test.exs b/test/pleroma/emails/mailer_test.exs
diff --git a/test/emails/user_email_test.exs b/test/pleroma/emails/user_email_test.exs
diff --git a/test/emoji/formatter_test.exs b/test/pleroma/emoji/formatter_test.exs
diff --git a/test/emoji/loader_test.exs b/test/pleroma/emoji/loader_test.exs
diff --git a/test/emoji_test.exs b/test/pleroma/emoji_test.exs
diff --git a/test/filter_test.exs b/test/pleroma/filter_test.exs
diff --git a/test/following_relationship_test.exs b/test/pleroma/following_relationship_test.exs
diff --git a/test/formatter_test.exs b/test/pleroma/formatter_test.exs
diff --git a/test/healthcheck_test.exs b/test/pleroma/healthcheck_test.exs
diff --git a/test/html_test.exs b/test/pleroma/html_test.exs
diff --git a/test/http/adapter_helper/gun_test.exs b/test/pleroma/http/adapter_helper/gun_test.exs
diff --git a/test/http/adapter_helper/hackney_test.exs b/test/pleroma/http/adapter_helper/hackney_test.exs
diff --git a/test/http/adapter_helper_test.exs b/test/pleroma/http/adapter_helper_test.exs
diff --git a/test/http/request_builder_test.exs b/test/pleroma/http/request_builder_test.exs
diff --git a/test/http_test.exs b/test/pleroma/http_test.exs
diff --git a/test/web/instances/instance_test.exs b/test/pleroma/instances/instance_test.exs
diff --git a/test/web/instances/instances_test.exs b/test/pleroma/instances_test.exs
diff --git a/test/federation/federation_test.exs b/test/pleroma/integration/federation_test.exs
diff --git a/test/integration/mastodon_websocket_test.exs b/test/pleroma/integration/mastodon_websocket_test.exs
diff --git a/test/job_queue_monitor_test.exs b/test/pleroma/job_queue_monitor_test.exs
diff --git a/test/keys_test.exs b/test/pleroma/keys_test.exs
diff --git a/test/list_test.exs b/test/pleroma/list_test.exs
diff --git a/test/marker_test.exs b/test/pleroma/marker_test.exs
diff --git a/test/mfa/backup_codes_test.exs b/test/pleroma/mfa/backup_codes_test.exs
diff --git a/test/mfa/totp_test.exs b/test/pleroma/mfa/totp_test.exs
diff --git a/test/mfa_test.exs b/test/pleroma/mfa_test.exs
diff --git a/test/migration_helper/notification_backfill_test.exs b/test/pleroma/migration_helper/notification_backfill_test.exs
diff --git a/test/moderation_log_test.exs b/test/pleroma/moderation_log_test.exs
diff --git a/test/notification_test.exs b/test/pleroma/notification_test.exs
diff --git a/test/object/containment_test.exs b/test/pleroma/object/containment_test.exs
diff --git a/test/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs
diff --git a/test/object_test.exs b/test/pleroma/object_test.exs
diff --git a/test/otp_version_test.exs b/test/pleroma/otp_version_test.exs
diff --git a/test/pagination_test.exs b/test/pleroma/pagination_test.exs
diff --git a/test/registration_test.exs b/test/pleroma/registration_test.exs
diff --git a/test/repo_test.exs b/test/pleroma/repo_test.exs
diff --git a/test/reverse_proxy/reverse_proxy_test.exs b/test/pleroma/reverse_proxy_test.exs
diff --git a/test/pleroma/runtime_test.exs b/test/pleroma/runtime_test.exs
@@ -0,0 +1,12 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.RuntimeTest do
+ use ExUnit.Case, async: true
+
+ test "it loads custom runtime modules" do
+ assert {:module, Fixtures.Modules.RuntimeModule} ==
+ Code.ensure_compiled(Fixtures.Modules.RuntimeModule)
+ end
+end
diff --git a/test/safe_jsonb_set_test.exs b/test/pleroma/safe_jsonb_set_test.exs
diff --git a/test/scheduled_activity_test.exs b/test/pleroma/scheduled_activity_test.exs
diff --git a/test/signature_test.exs b/test/pleroma/signature_test.exs
diff --git a/test/stats_test.exs b/test/pleroma/stats_test.exs
diff --git a/test/upload/filter/anonymize_filename_test.exs b/test/pleroma/upload/filter/anonymize_filename_test.exs
diff --git a/test/upload/filter/dedupe_test.exs b/test/pleroma/upload/filter/dedupe_test.exs
diff --git a/test/upload/filter/mogrifun_test.exs b/test/pleroma/upload/filter/mogrifun_test.exs
diff --git a/test/upload/filter/mogrify_test.exs b/test/pleroma/upload/filter/mogrify_test.exs
diff --git a/test/upload/filter_test.exs b/test/pleroma/upload/filter_test.exs
diff --git a/test/upload_test.exs b/test/pleroma/upload_test.exs
diff --git a/test/uploaders/local_test.exs b/test/pleroma/uploaders/local_test.exs
diff --git a/test/uploaders/s3_test.exs b/test/pleroma/uploaders/s3_test.exs
diff --git a/test/user/notification_setting_test.exs b/test/pleroma/user/notification_setting_test.exs
diff --git a/test/user_invite_token_test.exs b/test/pleroma/user_invite_token_test.exs
diff --git a/test/user_relationship_test.exs b/test/pleroma/user_relationship_test.exs
diff --git a/test/user_search_test.exs b/test/pleroma/user_search_test.exs
diff --git a/test/user_test.exs b/test/pleroma/user_test.exs
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
diff --git a/test/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs b/test/pleroma/web/activity_pub/force_bot_unlisted_policy_test.exs
diff --git a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs b/test/pleroma/web/activity_pub/mrf/activity_expiration_policy_test.exs
diff --git a/test/web/activity_pub/mrf/anti_followbot_policy_test.exs b/test/pleroma/web/activity_pub/mrf/anti_followbot_policy_test.exs
diff --git a/test/web/activity_pub/mrf/anti_link_spam_policy_test.exs b/test/pleroma/web/activity_pub/mrf/anti_link_spam_policy_test.exs
diff --git a/test/web/activity_pub/mrf/ensure_re_prepended_test.exs b/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs
diff --git a/test/web/activity_pub/mrf/hellthread_policy_test.exs b/test/pleroma/web/activity_pub/mrf/hellthread_policy_test.exs
diff --git a/test/web/activity_pub/mrf/keyword_policy_test.exs b/test/pleroma/web/activity_pub/mrf/keyword_policy_test.exs
diff --git a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs b/test/pleroma/web/activity_pub/mrf/media_proxy_warming_policy_test.exs
diff --git a/test/web/activity_pub/mrf/mention_policy_test.exs b/test/pleroma/web/activity_pub/mrf/mention_policy_test.exs
diff --git a/test/web/activity_pub/mrf/no_placeholder_text_policy_test.exs b/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs
diff --git a/test/web/activity_pub/mrf/normalize_markup_test.exs b/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs
diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/pleroma/web/activity_pub/mrf/object_age_policy_test.exs
diff --git a/test/web/activity_pub/mrf/reject_non_public_test.exs b/test/pleroma/web/activity_pub/mrf/reject_non_public_test.exs
diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs
diff --git a/test/web/activity_pub/mrf/steal_emoji_policy_test.exs b/test/pleroma/web/activity_pub/mrf/steal_emoji_policy_test.exs
diff --git a/test/web/activity_pub/mrf/subchain_policy_test.exs b/test/pleroma/web/activity_pub/mrf/subchain_policy_test.exs
diff --git a/test/web/activity_pub/mrf/tag_policy_test.exs b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs
diff --git a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs b/test/pleroma/web/activity_pub/mrf/user_allow_list_policy_test.exs
diff --git a/test/web/activity_pub/mrf/vocabulary_policy_test.exs b/test/pleroma/web/activity_pub/mrf/vocabulary_policy_test.exs
diff --git a/test/web/activity_pub/mrf/mrf_test.exs b/test/pleroma/web/activity_pub/mrf_test.exs
diff --git a/test/web/activity_pub/pipeline_test.exs b/test/pleroma/web/activity_pub/pipeline_test.exs
diff --git a/test/web/activity_pub/publisher_test.exs b/test/pleroma/web/activity_pub/publisher_test.exs
diff --git a/test/web/activity_pub/relay_test.exs b/test/pleroma/web/activity_pub/relay_test.exs
diff --git a/test/web/activity_pub/side_effects_test.exs b/test/pleroma/web/activity_pub/side_effects_test.exs
diff --git a/test/web/activity_pub/transmogrifier/announce_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs
diff --git a/test/web/activity_pub/transmogrifier/chat_message_test.exs b/test/pleroma/web/activity_pub/transmogrifier/chat_message_test.exs
diff --git a/test/web/activity_pub/transmogrifier/delete_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
diff --git a/test/web/activity_pub/transmogrifier/emoji_react_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/follow_handling_test.exs
diff --git a/test/web/activity_pub/transmogrifier/like_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/like_handling_test.exs
diff --git a/test/web/activity_pub/transmogrifier/undo_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/undo_handling_test.exs
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs
diff --git a/test/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs
diff --git a/test/web/activity_pub/views/object_view_test.exs b/test/pleroma/web/activity_pub/views/object_view_test.exs
diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs
diff --git a/test/web/activity_pub/visibilty_test.exs b/test/pleroma/web/activity_pub/visibility_test.exs
diff --git a/test/web/admin_api/controllers/admin_api_controller_test.exs b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs
diff --git a/test/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs
diff --git a/test/web/admin_api/controllers/invite_controller_test.exs b/test/pleroma/web/admin_api/controllers/invite_controller_test.exs
diff --git a/test/web/admin_api/controllers/media_proxy_cache_controller_test.exs b/test/pleroma/web/admin_api/controllers/media_proxy_cache_controller_test.exs
diff --git a/test/web/admin_api/controllers/oauth_app_controller_test.exs b/test/pleroma/web/admin_api/controllers/oauth_app_controller_test.exs
diff --git a/test/web/admin_api/controllers/relay_controller_test.exs b/test/pleroma/web/admin_api/controllers/relay_controller_test.exs
diff --git a/test/web/admin_api/controllers/report_controller_test.exs b/test/pleroma/web/admin_api/controllers/report_controller_test.exs
diff --git a/test/web/admin_api/controllers/status_controller_test.exs b/test/pleroma/web/admin_api/controllers/status_controller_test.exs
diff --git a/test/web/admin_api/search_test.exs b/test/pleroma/web/admin_api/search_test.exs
diff --git a/test/web/admin_api/views/report_view_test.exs b/test/pleroma/web/admin_api/views/report_view_test.exs
diff --git a/test/web/api_spec/schema_examples_test.exs b/test/pleroma/web/api_spec/schema_examples_test.exs
diff --git a/test/pleroma/web/auth/auth_controller_test.exs b/test/pleroma/web/auth/auth_controller_test.exs
@@ -0,0 +1,242 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Auth.AuthControllerTest do
+ use Pleroma.Web.ConnCase
+
+ import Pleroma.Factory
+
+ describe "do_oauth_check" do
+ test "serves with proper OAuth token (fulfilling requested scopes)" do
+ %{conn: good_token_conn, user: user} = oauth_access(["read"])
+
+ assert %{"user_id" => user.id} ==
+ good_token_conn
+ |> get("/test/authenticated_api/do_oauth_check")
+ |> json_response(200)
+
+ # Unintended usage (:api) — use with :authenticated_api instead
+ assert %{"user_id" => user.id} ==
+ good_token_conn
+ |> get("/test/api/do_oauth_check")
+ |> json_response(200)
+ end
+
+ test "fails on no token / missing scope(s)" do
+ %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
+
+ bad_token_conn
+ |> get("/test/authenticated_api/do_oauth_check")
+ |> json_response(403)
+
+ bad_token_conn
+ |> assign(:token, nil)
+ |> get("/test/api/do_oauth_check")
+ |> json_response(403)
+ end
+ end
+
+ describe "fallback_oauth_check" do
+ test "serves with proper OAuth token (fulfilling requested scopes)" do
+ %{conn: good_token_conn, user: user} = oauth_access(["read"])
+
+ assert %{"user_id" => user.id} ==
+ good_token_conn
+ |> get("/test/api/fallback_oauth_check")
+ |> json_response(200)
+
+ # Unintended usage (:authenticated_api) — use with :api instead
+ assert %{"user_id" => user.id} ==
+ good_token_conn
+ |> get("/test/authenticated_api/fallback_oauth_check")
+ |> json_response(200)
+ end
+
+ test "for :api on public instance, drops :user and renders on no token / missing scope(s)" do
+ clear_config([:instance, :public], true)
+
+ %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
+
+ assert %{"user_id" => nil} ==
+ bad_token_conn
+ |> get("/test/api/fallback_oauth_check")
+ |> json_response(200)
+
+ assert %{"user_id" => nil} ==
+ bad_token_conn
+ |> assign(:token, nil)
+ |> get("/test/api/fallback_oauth_check")
+ |> json_response(200)
+ end
+
+ test "for :api on private instance, fails on no token / missing scope(s)" do
+ clear_config([:instance, :public], false)
+
+ %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
+
+ bad_token_conn
+ |> get("/test/api/fallback_oauth_check")
+ |> json_response(403)
+
+ bad_token_conn
+ |> assign(:token, nil)
+ |> get("/test/api/fallback_oauth_check")
+ |> json_response(403)
+ end
+ end
+
+ describe "skip_oauth_check" do
+ test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
+ user = insert(:user)
+
+ assert %{"user_id" => user.id} ==
+ build_conn()
+ |> assign(:user, user)
+ |> get("/test/authenticated_api/skip_oauth_check")
+ |> json_response(200)
+
+ %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
+
+ assert %{"user_id" => user.id} ==
+ bad_token_conn
+ |> get("/test/authenticated_api/skip_oauth_check")
+ |> json_response(200)
+ end
+
+ test "serves via :api on public instance if :user is not set" do
+ clear_config([:instance, :public], true)
+
+ assert %{"user_id" => nil} ==
+ build_conn()
+ |> get("/test/api/skip_oauth_check")
+ |> json_response(200)
+
+ build_conn()
+ |> get("/test/authenticated_api/skip_oauth_check")
+ |> json_response(403)
+ end
+
+ test "fails on private instance if :user is not set" do
+ clear_config([:instance, :public], false)
+
+ build_conn()
+ |> get("/test/api/skip_oauth_check")
+ |> json_response(403)
+
+ build_conn()
+ |> get("/test/authenticated_api/skip_oauth_check")
+ |> json_response(403)
+ end
+ end
+
+ describe "fallback_oauth_skip_publicity_check" do
+ test "serves with proper OAuth token (fulfilling requested scopes)" do
+ %{conn: good_token_conn, user: user} = oauth_access(["read"])
+
+ assert %{"user_id" => user.id} ==
+ good_token_conn
+ |> get("/test/api/fallback_oauth_skip_publicity_check")
+ |> json_response(200)
+
+ # Unintended usage (:authenticated_api)
+ assert %{"user_id" => user.id} ==
+ good_token_conn
+ |> get("/test/authenticated_api/fallback_oauth_skip_publicity_check")
+ |> json_response(200)
+ end
+
+ test "for :api on private / public instance, drops :user and renders on token issue" do
+ %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
+
+ for is_public <- [true, false] do
+ clear_config([:instance, :public], is_public)
+
+ assert %{"user_id" => nil} ==
+ bad_token_conn
+ |> get("/test/api/fallback_oauth_skip_publicity_check")
+ |> json_response(200)
+
+ assert %{"user_id" => nil} ==
+ bad_token_conn
+ |> assign(:token, nil)
+ |> get("/test/api/fallback_oauth_skip_publicity_check")
+ |> json_response(200)
+ end
+ end
+ end
+
+ describe "skip_oauth_skip_publicity_check" do
+ test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
+ user = insert(:user)
+
+ assert %{"user_id" => user.id} ==
+ build_conn()
+ |> assign(:user, user)
+ |> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
+ |> json_response(200)
+
+ %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
+
+ assert %{"user_id" => user.id} ==
+ bad_token_conn
+ |> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
+ |> json_response(200)
+ end
+
+ test "for :api, serves on private and public instances regardless of whether :user is set" do
+ user = insert(:user)
+
+ for is_public <- [true, false] do
+ clear_config([:instance, :public], is_public)
+
+ assert %{"user_id" => nil} ==
+ build_conn()
+ |> get("/test/api/skip_oauth_skip_publicity_check")
+ |> json_response(200)
+
+ assert %{"user_id" => user.id} ==
+ build_conn()
+ |> assign(:user, user)
+ |> get("/test/api/skip_oauth_skip_publicity_check")
+ |> json_response(200)
+ end
+ end
+ end
+
+ describe "missing_oauth_check_definition" do
+ def test_missing_oauth_check_definition_failure(endpoint, expected_error) do
+ %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
+
+ assert %{"error" => expected_error} ==
+ conn
+ |> get(endpoint)
+ |> json_response(403)
+ end
+
+ test "fails if served via :authenticated_api" do
+ test_missing_oauth_check_definition_failure(
+ "/test/authenticated_api/missing_oauth_check_definition",
+ "Security violation: OAuth scopes check was neither handled nor explicitly skipped."
+ )
+ end
+
+ test "fails if served via :api and the instance is private" do
+ clear_config([:instance, :public], false)
+
+ test_missing_oauth_check_definition_failure(
+ "/test/api/missing_oauth_check_definition",
+ "This resource requires authentication."
+ )
+ end
+
+ test "succeeds with dropped :user if served via :api on public instance" do
+ %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
+
+ assert %{"user_id" => nil} ==
+ conn
+ |> get("/test/api/missing_oauth_check_definition")
+ |> json_response(200)
+ end
+ end
+end
diff --git a/test/web/auth/authenticator_test.exs b/test/pleroma/web/auth/authenticator_test.exs
diff --git a/test/web/auth/basic_auth_test.exs b/test/pleroma/web/auth/basic_auth_test.exs
diff --git a/test/web/auth/pleroma_authenticator_test.exs b/test/pleroma/web/auth/pleroma_authenticator_test.exs
diff --git a/test/web/auth/totp_authenticator_test.exs b/test/pleroma/web/auth/totp_authenticator_test.exs
diff --git a/test/web/chat_channel_test.exs b/test/pleroma/web/chat_channel_test.exs
diff --git a/test/web/common_api/common_api_utils_test.exs b/test/pleroma/web/common_api/utils_test.exs
diff --git a/test/web/common_api/common_api_test.exs b/test/pleroma/web/common_api_test.exs
diff --git a/test/web/fallback_test.exs b/test/pleroma/web/fallback_test.exs
diff --git a/test/web/federator_test.exs b/test/pleroma/web/federator_test.exs
diff --git a/test/web/feed/tag_controller_test.exs b/test/pleroma/web/feed/tag_controller_test.exs
diff --git a/test/web/feed/user_controller_test.exs b/test/pleroma/web/feed/user_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/app_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/app_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/auth_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/auth_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/conversation_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/custom_emoji_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/domain_block_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/follow_request_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/list_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/list_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/marker_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/marker_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/media_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/media_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/poll_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/poll_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/report_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/scheduled_activity_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/search_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/subscription_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/suggestion_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs
diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
diff --git a/test/pleroma/web/mastodon_api/masto_fe_controller_test.exs b/test/pleroma/web/mastodon_api/masto_fe_controller_test.exs
@@ -0,0 +1,85 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.MastoFEControllerTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.Config
+ alias Pleroma.User
+
+ import Pleroma.Factory
+
+ setup do: clear_config([:instance, :public])
+
+ test "put settings", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"]))
+ |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
+
+ assert _result = json_response(conn, 200)
+
+ user = User.get_cached_by_ap_id(user.ap_id)
+ assert user.mastofe_settings == %{"programming" => "socks"}
+ end
+
+ describe "index/2 redirections" do
+ setup %{conn: conn} do
+ session_opts = [
+ store: :cookie,
+ key: "_test",
+ signing_salt: "cooldude"
+ ]
+
+ conn =
+ conn
+ |> Plug.Session.call(Plug.Session.init(session_opts))
+ |> fetch_session()
+
+ test_path = "/web/statuses/test"
+ %{conn: conn, path: test_path}
+ end
+
+ test "redirects not logged-in users to the login page", %{conn: conn, path: path} do
+ conn = get(conn, path)
+
+ assert conn.status == 302
+ assert redirected_to(conn) == "/web/login"
+ end
+
+ test "redirects not logged-in users to the login page on private instances", %{
+ conn: conn,
+ path: path
+ } do
+ Config.put([:instance, :public], false)
+
+ conn = get(conn, path)
+
+ assert conn.status == 302
+ assert redirected_to(conn) == "/web/login"
+ end
+
+ test "does not redirect logged in users to the login page", %{conn: conn, path: path} do
+ token = insert(:oauth_token, scopes: ["read"])
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> get(path)
+
+ assert conn.status == 200
+ end
+
+ test "saves referer path to session", %{conn: conn, path: path} do
+ conn = get(conn, path)
+ return_to = Plug.Conn.get_session(conn, :return_to)
+
+ assert return_to == path
+ end
+ end
+end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/pleroma/web/mastodon_api/mastodon_api_controller_test.exs
diff --git a/test/web/mastodon_api/mastodon_api_test.exs b/test/pleroma/web/mastodon_api/mastodon_api_test.exs
diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs
@@ -0,0 +1,529 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
+ alias Pleroma.Repo
+ alias Pleroma.User
+
+ use Pleroma.Web.ConnCase
+
+ import Mock
+ import Pleroma.Factory
+
+ setup do: clear_config([:instance, :max_account_fields])
+
+ describe "updating credentials" do
+ setup do: oauth_access(["write:accounts"])
+ setup :request_content_type
+
+ test "sets user settings in a generic way", %{conn: conn} do
+ res_conn =
+ patch(conn, "/api/v1/accounts/update_credentials", %{
+ "pleroma_settings_store" => %{
+ pleroma_fe: %{
+ theme: "bla"
+ }
+ }
+ })
+
+ assert user_data = json_response_and_validate_schema(res_conn, 200)
+ assert user_data["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}}
+
+ user = Repo.get(User, user_data["id"])
+
+ res_conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/accounts/update_credentials", %{
+ "pleroma_settings_store" => %{
+ masto_fe: %{
+ theme: "bla"
+ }
+ }
+ })
+
+ assert user_data = json_response_and_validate_schema(res_conn, 200)
+
+ assert user_data["pleroma"]["settings_store"] ==
+ %{
+ "pleroma_fe" => %{"theme" => "bla"},
+ "masto_fe" => %{"theme" => "bla"}
+ }
+
+ user = Repo.get(User, user_data["id"])
+
+ clear_config([:instance, :federating], true)
+
+ with_mock Pleroma.Web.Federator,
+ publish: fn _activity -> :ok end do
+ res_conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/accounts/update_credentials", %{
+ "pleroma_settings_store" => %{
+ masto_fe: %{
+ theme: "blub"
+ }
+ }
+ })
+
+ assert user_data = json_response_and_validate_schema(res_conn, 200)
+
+ assert user_data["pleroma"]["settings_store"] ==
+ %{
+ "pleroma_fe" => %{"theme" => "bla"},
+ "masto_fe" => %{"theme" => "blub"}
+ }
+
+ assert_called(Pleroma.Web.Federator.publish(:_))
+ end
+ end
+
+ test "updates the user's bio", %{conn: conn} do
+ user2 = insert(:user)
+
+ raw_bio = "I drink #cofe with @#{user2.nickname}\n\nsuya.."
+
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+
+ assert user_data["note"] ==
+ ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a class="u-url mention" data-user="#{
+ user2.id
+ }" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..)
+
+ assert user_data["source"]["note"] == raw_bio
+
+ user = Repo.get(User, user_data["id"])
+
+ assert user.raw_bio == raw_bio
+ end
+
+ test "updates the user's locking status", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["locked"] == true
+ end
+
+ test "updates the user's chat acceptance status", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{accepts_chat_messages: "false"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["pleroma"]["accepts_chat_messages"] == false
+ end
+
+ test "updates the user's allow_following_move", %{user: user, conn: conn} do
+ assert user.allow_following_move == true
+
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{allow_following_move: "false"})
+
+ assert refresh_record(user).allow_following_move == false
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["pleroma"]["allow_following_move"] == false
+ end
+
+ test "updates the user's default scope", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "unlisted"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["source"]["privacy"] == "unlisted"
+ end
+
+ test "updates the user's privacy", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{source: %{privacy: "unlisted"}})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["source"]["privacy"] == "unlisted"
+ end
+
+ test "updates the user's hide_followers status", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["pleroma"]["hide_followers"] == true
+ end
+
+ test "updates the user's discoverable status", %{conn: conn} do
+ assert %{"source" => %{"pleroma" => %{"discoverable" => true}}} =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{discoverable: "true"})
+ |> json_response_and_validate_schema(:ok)
+
+ assert %{"source" => %{"pleroma" => %{"discoverable" => false}}} =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{discoverable: "false"})
+ |> json_response_and_validate_schema(:ok)
+ end
+
+ test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do
+ conn =
+ patch(conn, "/api/v1/accounts/update_credentials", %{
+ hide_followers_count: "true",
+ hide_follows_count: "true"
+ })
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["pleroma"]["hide_followers_count"] == true
+ assert user_data["pleroma"]["hide_follows_count"] == true
+ end
+
+ test "updates the user's skip_thread_containment option", %{user: user, conn: conn} do
+ response =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"})
+ |> json_response_and_validate_schema(200)
+
+ assert response["pleroma"]["skip_thread_containment"] == true
+ assert refresh_record(user).skip_thread_containment
+ end
+
+ test "updates the user's hide_follows status", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_follows: "true"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["pleroma"]["hide_follows"] == true
+ end
+
+ test "updates the user's hide_favorites status", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_favorites: "true"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["pleroma"]["hide_favorites"] == true
+ end
+
+ test "updates the user's show_role status", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{show_role: "false"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["source"]["pleroma"]["show_role"] == false
+ end
+
+ test "updates the user's no_rich_text status", %{conn: conn} do
+ conn = patch(conn, "/api/v1/accounts/update_credentials", %{no_rich_text: "true"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["source"]["pleroma"]["no_rich_text"] == true
+ end
+
+ test "updates the user's name", %{conn: conn} do
+ conn =
+ patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"})
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+ assert user_data["display_name"] == "markorepairs"
+
+ update_activity = Repo.one(Pleroma.Activity)
+ assert update_activity.data["type"] == "Update"
+ assert update_activity.data["object"]["name"] == "markorepairs"
+ end
+
+ test "updates the user's avatar", %{user: user, conn: conn} do
+ new_avatar = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ assert user.avatar == %{}
+
+ res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
+
+ assert user_response = json_response_and_validate_schema(res, 200)
+ assert user_response["avatar"] != User.avatar_url(user)
+
+ user = User.get_by_id(user.id)
+ refute user.avatar == %{}
+
+ # Also resets it
+ _res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => ""})
+
+ user = User.get_by_id(user.id)
+ assert user.avatar == nil
+ end
+
+ test "updates the user's banner", %{user: user, conn: conn} do
+ new_header = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
+
+ assert user_response = json_response_and_validate_schema(res, 200)
+ assert user_response["header"] != User.banner_url(user)
+
+ # Also resets it
+ _res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => ""})
+
+ user = User.get_by_id(user.id)
+ assert user.banner == nil
+ end
+
+ test "updates the user's background", %{conn: conn, user: user} do
+ new_header = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ res =
+ patch(conn, "/api/v1/accounts/update_credentials", %{
+ "pleroma_background_image" => new_header
+ })
+
+ assert user_response = json_response_and_validate_schema(res, 200)
+ assert user_response["pleroma"]["background_image"]
+ #
+ # Also resets it
+ _res =
+ patch(conn, "/api/v1/accounts/update_credentials", %{"pleroma_background_image" => ""})
+
+ user = User.get_by_id(user.id)
+ assert user.background == nil
+ end
+
+ test "requires 'write:accounts' permission" do
+ token1 = insert(:oauth_token, scopes: ["read"])
+ token2 = insert(:oauth_token, scopes: ["write", "follow"])
+
+ for token <- [token1, token2] do
+ conn =
+ build_conn()
+ |> put_req_header("content-type", "multipart/form-data")
+ |> put_req_header("authorization", "Bearer #{token.token}")
+ |> patch("/api/v1/accounts/update_credentials", %{})
+
+ if token == token1 do
+ assert %{"error" => "Insufficient permissions: write:accounts."} ==
+ json_response_and_validate_schema(conn, 403)
+ else
+ assert json_response_and_validate_schema(conn, 200)
+ end
+ end
+ end
+
+ test "updates profile emojos", %{user: user, conn: conn} do
+ note = "*sips :blank:*"
+ name = "I am :firefox:"
+
+ ret_conn =
+ patch(conn, "/api/v1/accounts/update_credentials", %{
+ "note" => note,
+ "display_name" => name
+ })
+
+ assert json_response_and_validate_schema(ret_conn, 200)
+
+ conn = get(conn, "/api/v1/accounts/#{user.id}")
+
+ assert user_data = json_response_and_validate_schema(conn, 200)
+
+ assert user_data["note"] == note
+ assert user_data["display_name"] == name
+ assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user_data["emojis"]
+ end
+
+ test "update fields", %{conn: conn} do
+ fields = [
+ %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>"},
+ %{"name" => "link.io", "value" => "cofe.io"}
+ ]
+
+ account_data =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
+ |> json_response_and_validate_schema(200)
+
+ assert account_data["fields"] == [
+ %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"},
+ %{
+ "name" => "link.io",
+ "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)
+ }
+ ]
+
+ assert account_data["source"]["fields"] == [
+ %{
+ "name" => "<a href=\"http://google.com\">foo</a>",
+ "value" => "<script>bar</script>"
+ },
+ %{"name" => "link.io", "value" => "cofe.io"}
+ ]
+ end
+
+ test "emojis in fields labels", %{conn: conn} do
+ fields = [
+ %{"name" => ":firefox:", "value" => "is best 2hu"},
+ %{"name" => "they wins", "value" => ":blank:"}
+ ]
+
+ account_data =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
+ |> json_response_and_validate_schema(200)
+
+ assert account_data["fields"] == [
+ %{"name" => ":firefox:", "value" => "is best 2hu"},
+ %{"name" => "they wins", "value" => ":blank:"}
+ ]
+
+ assert account_data["source"]["fields"] == [
+ %{"name" => ":firefox:", "value" => "is best 2hu"},
+ %{"name" => "they wins", "value" => ":blank:"}
+ ]
+
+ assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = account_data["emojis"]
+ end
+
+ test "update fields via x-www-form-urlencoded", %{conn: conn} do
+ fields =
+ [
+ "fields_attributes[1][name]=link",
+ "fields_attributes[1][value]=http://cofe.io",
+ "fields_attributes[0][name]=foo",
+ "fields_attributes[0][value]=bar"
+ ]
+ |> Enum.join("&")
+
+ account =
+ conn
+ |> put_req_header("content-type", "application/x-www-form-urlencoded")
+ |> patch("/api/v1/accounts/update_credentials", fields)
+ |> json_response_and_validate_schema(200)
+
+ assert account["fields"] == [
+ %{"name" => "foo", "value" => "bar"},
+ %{
+ "name" => "link",
+ "value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>)
+ }
+ ]
+
+ assert account["source"]["fields"] == [
+ %{"name" => "foo", "value" => "bar"},
+ %{"name" => "link", "value" => "http://cofe.io"}
+ ]
+ end
+
+ test "update fields with empty name", %{conn: conn} do
+ fields = [
+ %{"name" => "foo", "value" => ""},
+ %{"name" => "", "value" => "bar"}
+ ]
+
+ account =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
+ |> json_response_and_validate_schema(200)
+
+ assert account["fields"] == [
+ %{"name" => "foo", "value" => ""}
+ ]
+ end
+
+ test "update fields when invalid request", %{conn: conn} do
+ name_limit = Pleroma.Config.get([:instance, :account_field_name_length])
+ value_limit = Pleroma.Config.get([:instance, :account_field_value_length])
+
+ long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join()
+ long_value = Enum.map(0..value_limit, fn _ -> "x" end) |> Enum.join()
+
+ fields = [%{"name" => "foo", "value" => long_value}]
+
+ assert %{"error" => "Invalid request"} ==
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
+ |> json_response_and_validate_schema(403)
+
+ fields = [%{"name" => long_name, "value" => "bar"}]
+
+ assert %{"error" => "Invalid request"} ==
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
+ |> json_response_and_validate_schema(403)
+
+ Pleroma.Config.put([:instance, :max_account_fields], 1)
+
+ fields = [
+ %{"name" => "foo", "value" => "bar"},
+ %{"name" => "link", "value" => "cofe.io"}
+ ]
+
+ assert %{"error" => "Invalid request"} ==
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
+ |> json_response_and_validate_schema(403)
+ end
+ end
+
+ describe "Mark account as bot" do
+ setup do: oauth_access(["write:accounts"])
+ setup :request_content_type
+
+ test "changing actor_type to Service makes account a bot", %{conn: conn} do
+ account =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Service"})
+ |> json_response_and_validate_schema(200)
+
+ assert account["bot"]
+ assert account["source"]["pleroma"]["actor_type"] == "Service"
+ end
+
+ test "changing actor_type to Person makes account a human", %{conn: conn} do
+ account =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Person"})
+ |> json_response_and_validate_schema(200)
+
+ refute account["bot"]
+ assert account["source"]["pleroma"]["actor_type"] == "Person"
+ end
+
+ test "changing actor_type to Application causes error", %{conn: conn} do
+ response =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Application"})
+ |> json_response_and_validate_schema(403)
+
+ assert %{"error" => "Invalid request"} == response
+ end
+
+ test "changing bot field to true changes actor_type to Service", %{conn: conn} do
+ account =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{bot: "true"})
+ |> json_response_and_validate_schema(200)
+
+ assert account["bot"]
+ assert account["source"]["pleroma"]["actor_type"] == "Service"
+ end
+
+ test "changing bot field to false changes actor_type to Person", %{conn: conn} do
+ account =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{bot: "false"})
+ |> json_response_and_validate_schema(200)
+
+ refute account["bot"]
+ assert account["source"]["pleroma"]["actor_type"] == "Person"
+ end
+
+ test "actor_type field has a higher priority than bot", %{conn: conn} do
+ account =
+ conn
+ |> patch("/api/v1/accounts/update_credentials", %{
+ actor_type: "Person",
+ bot: "true"
+ })
+ |> json_response_and_validate_schema(200)
+
+ refute account["bot"]
+ assert account["source"]["pleroma"]["actor_type"] == "Person"
+ end
+ end
+end
diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs
diff --git a/test/web/mastodon_api/views/conversation_view_test.exs b/test/pleroma/web/mastodon_api/views/conversation_view_test.exs
diff --git a/test/web/mastodon_api/views/list_view_test.exs b/test/pleroma/web/mastodon_api/views/list_view_test.exs
diff --git a/test/web/mastodon_api/views/marker_view_test.exs b/test/pleroma/web/mastodon_api/views/marker_view_test.exs
diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/pleroma/web/mastodon_api/views/notification_view_test.exs
diff --git a/test/web/mastodon_api/views/poll_view_test.exs b/test/pleroma/web/mastodon_api/views/poll_view_test.exs
diff --git a/test/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs
diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs
diff --git a/test/web/mastodon_api/views/subscription_view_test.exs b/test/pleroma/web/mastodon_api/views/subscription_view_test.exs
diff --git a/test/web/media_proxy/invalidations/http_test.exs b/test/pleroma/web/media_proxy/invalidation/http_test.exs
diff --git a/test/web/media_proxy/invalidations/script_test.exs b/test/pleroma/web/media_proxy/invalidation/script_test.exs
diff --git a/test/web/media_proxy/invalidation_test.exs b/test/pleroma/web/media_proxy/invalidation_test.exs
diff --git a/test/web/media_proxy/media_proxy_controller_test.exs b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
diff --git a/test/web/media_proxy/media_proxy_test.exs b/test/pleroma/web/media_proxy_test.exs
diff --git a/test/web/metadata/player_view_test.exs b/test/pleroma/web/metadata/player_view_test.exs
diff --git a/test/web/metadata/feed_test.exs b/test/pleroma/web/metadata/providers/feed_test.exs
diff --git a/test/web/metadata/opengraph_test.exs b/test/pleroma/web/metadata/providers/open_graph_test.exs
diff --git a/test/web/metadata/rel_me_test.exs b/test/pleroma/web/metadata/providers/rel_me_test.exs
diff --git a/test/web/metadata/restrict_indexing_test.exs b/test/pleroma/web/metadata/providers/restrict_indexing_test.exs
diff --git a/test/web/metadata/twitter_card_test.exs b/test/pleroma/web/metadata/providers/twitter_card_test.exs
diff --git a/test/web/metadata/utils_test.exs b/test/pleroma/web/metadata/utils_test.exs
diff --git a/test/web/metadata/metadata_test.exs b/test/pleroma/web/metadata_test.exs
diff --git a/test/pleroma/web/mongoose_im_controller_test.exs b/test/pleroma/web/mongoose_im_controller_test.exs
@@ -0,0 +1,81 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MongooseIMControllerTest do
+ use Pleroma.Web.ConnCase
+ import Pleroma.Factory
+
+ test "/user_exists", %{conn: conn} do
+ _user = insert(:user, nickname: "lain")
+ _remote_user = insert(:user, nickname: "alice", local: false)
+ _deactivated_user = insert(:user, nickname: "konata", deactivated: true)
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :user_exists), user: "lain")
+ |> json_response(200)
+
+ assert res == true
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :user_exists), user: "alice")
+ |> json_response(404)
+
+ assert res == false
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :user_exists), user: "bob")
+ |> json_response(404)
+
+ assert res == false
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :user_exists), user: "konata")
+ |> json_response(404)
+
+ assert res == false
+ end
+
+ test "/check_password", %{conn: conn} do
+ user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt("cool"))
+
+ _deactivated_user =
+ insert(:user,
+ nickname: "konata",
+ deactivated: true,
+ password_hash: Pbkdf2.hash_pwd_salt("cool")
+ )
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "cool")
+ |> json_response(200)
+
+ assert res == true
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "uncool")
+ |> json_response(403)
+
+ assert res == false
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :check_password), user: "konata", pass: "cool")
+ |> json_response(404)
+
+ assert res == false
+
+ res =
+ conn
+ |> get(mongoose_im_path(conn, :check_password), user: "nobody", pass: "cool")
+ |> json_response(404)
+
+ assert res == false
+ end
+end
diff --git a/test/web/node_info_test.exs b/test/pleroma/web/node_info_test.exs
diff --git a/test/web/oauth/app_test.exs b/test/pleroma/web/o_auth/app_test.exs
diff --git a/test/web/oauth/authorization_test.exs b/test/pleroma/web/o_auth/authorization_test.exs
diff --git a/test/web/oauth/ldap_authorization_test.exs b/test/pleroma/web/o_auth/ldap_authorization_test.exs
diff --git a/test/web/oauth/mfa_controller_test.exs b/test/pleroma/web/o_auth/mfa_controller_test.exs
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/pleroma/web/o_auth/o_auth_controller_test.exs
diff --git a/test/web/oauth/token/utils_test.exs b/test/pleroma/web/o_auth/token/utils_test.exs
diff --git a/test/web/oauth/token_test.exs b/test/pleroma/web/o_auth/token_test.exs
diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/pleroma/web/o_status/o_status_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/account_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/chat_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/conversation_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/conversation_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_pack_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/mascot_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/mascot_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/notification_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/scrobble_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/scrobble_controller_test.exs
diff --git a/test/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
diff --git a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs
@@ -0,0 +1,72 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Chat
+ alias Pleroma.Chat.MessageReference
+ alias Pleroma.Object
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
+
+ import Pleroma.Factory
+
+ test "it displays a chat message" do
+ user = insert(:user)
+ recipient = insert(:user)
+
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
+ {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "kippis :firefox:")
+
+ chat = Chat.get(user.id, recipient.ap_id)
+
+ object = Object.normalize(activity)
+
+ cm_ref = MessageReference.for_chat_and_object(chat, object)
+
+ chat_message = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
+
+ assert chat_message[:id] == cm_ref.id
+ assert chat_message[:content] == "kippis :firefox:"
+ assert chat_message[:account_id] == user.id
+ assert chat_message[:chat_id]
+ assert chat_message[:created_at]
+ assert chat_message[:unread] == false
+ assert match?([%{shortcode: "firefox"}], chat_message[:emojis])
+
+ clear_config([:rich_media, :enabled], true)
+
+ Tesla.Mock.mock(fn
+ %{url: "https://example.com/ogp"} ->
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
+ end)
+
+ {:ok, activity} =
+ CommonAPI.post_chat_message(recipient, user, "gkgkgk https://example.com/ogp",
+ media_id: upload.id
+ )
+
+ object = Object.normalize(activity)
+
+ cm_ref = MessageReference.for_chat_and_object(chat, object)
+
+ chat_message_two = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
+
+ assert chat_message_two[:id] == cm_ref.id
+ assert chat_message_two[:content] == object.data["content"]
+ assert chat_message_two[:account_id] == recipient.id
+ assert chat_message_two[:chat_id] == chat_message[:chat_id]
+ assert chat_message_two[:attachment]
+ assert chat_message_two[:unread] == true
+ assert chat_message_two[:card]
+ end
+end
diff --git a/test/web/pleroma_api/views/chat_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_view_test.exs
diff --git a/test/web/pleroma_api/views/scrobble_view_test.exs b/test/pleroma/web/pleroma_api/views/scrobble_view_test.exs
diff --git a/test/pleroma/web/plugs/admin_secret_authentication_plug_test.exs b/test/pleroma/web/plugs/admin_secret_authentication_plug_test.exs
@@ -0,0 +1,75 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.AdminSecretAuthenticationPlugTest do
+ use Pleroma.Web.ConnCase
+
+ import Mock
+ import Pleroma.Factory
+
+ alias Pleroma.Plugs.AdminSecretAuthenticationPlug
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.Plugs.PlugHelper
+ alias Pleroma.Plugs.RateLimiter
+
+ test "does nothing if a user is assigned", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+
+ ret_conn =
+ conn
+ |> AdminSecretAuthenticationPlug.call(%{})
+
+ assert conn == ret_conn
+ end
+
+ describe "when secret set it assigns an admin user" do
+ setup do: clear_config([:admin_token])
+
+ setup_with_mocks([{RateLimiter, [:passthrough], []}]) do
+ :ok
+ end
+
+ test "with `admin_token` query parameter", %{conn: conn} do
+ Pleroma.Config.put(:admin_token, "password123")
+
+ conn =
+ %{conn | params: %{"admin_token" => "wrong_password"}}
+ |> AdminSecretAuthenticationPlug.call(%{})
+
+ refute conn.assigns[:user]
+ assert called(RateLimiter.call(conn, name: :authentication))
+
+ conn =
+ %{conn | params: %{"admin_token" => "password123"}}
+ |> AdminSecretAuthenticationPlug.call(%{})
+
+ assert conn.assigns[:user].is_admin
+ assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
+ end
+
+ test "with `x-admin-token` HTTP header", %{conn: conn} do
+ Pleroma.Config.put(:admin_token, "☕️")
+
+ conn =
+ conn
+ |> put_req_header("x-admin-token", "🥛")
+ |> AdminSecretAuthenticationPlug.call(%{})
+
+ refute conn.assigns[:user]
+ assert called(RateLimiter.call(conn, name: :authentication))
+
+ conn =
+ conn
+ |> put_req_header("x-admin-token", "☕️")
+ |> AdminSecretAuthenticationPlug.call(%{})
+
+ assert conn.assigns[:user].is_admin
+ assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
+ end
+ end
+end
diff --git a/test/pleroma/web/plugs/authentication_plug_test.exs b/test/pleroma/web/plugs/authentication_plug_test.exs
@@ -0,0 +1,125 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.AuthenticationPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.AuthenticationPlug
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.Plugs.PlugHelper
+ alias Pleroma.User
+
+ import ExUnit.CaptureLog
+ import Pleroma.Factory
+
+ setup %{conn: conn} do
+ user = %User{
+ id: 1,
+ name: "dude",
+ password_hash: Pbkdf2.hash_pwd_salt("guy")
+ }
+
+ conn =
+ conn
+ |> assign(:auth_user, user)
+
+ %{user: user, conn: conn}
+ end
+
+ test "it does nothing if a user is assigned", %{conn: conn} do
+ conn =
+ conn
+ |> assign(:user, %User{})
+
+ ret_conn =
+ conn
+ |> AuthenticationPlug.call(%{})
+
+ assert ret_conn == conn
+ end
+
+ test "with a correct password in the credentials, " <>
+ "it assigns the auth_user and marks OAuthScopesPlug as skipped",
+ %{conn: conn} do
+ conn =
+ conn
+ |> assign(:auth_credentials, %{password: "guy"})
+ |> AuthenticationPlug.call(%{})
+
+ assert conn.assigns.user == conn.assigns.auth_user
+ assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
+ end
+
+ test "with a bcrypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
+ user = insert(:user, password_hash: Bcrypt.hash_pwd_salt("123"))
+ assert "$2" <> _ = user.password_hash
+
+ conn =
+ conn
+ |> assign(:auth_user, user)
+ |> assign(:auth_credentials, %{password: "123"})
+ |> AuthenticationPlug.call(%{})
+
+ assert conn.assigns.user.id == conn.assigns.auth_user.id
+ assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
+
+ user = User.get_by_id(user.id)
+ assert "$pbkdf2" <> _ = user.password_hash
+ end
+
+ @tag :skip_on_mac
+ test "with a crypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
+ user =
+ insert(:user,
+ password_hash:
+ "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
+ )
+
+ conn =
+ conn
+ |> assign(:auth_user, user)
+ |> assign(:auth_credentials, %{password: "password"})
+ |> AuthenticationPlug.call(%{})
+
+ assert conn.assigns.user.id == conn.assigns.auth_user.id
+ assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
+
+ user = User.get_by_id(user.id)
+ assert "$pbkdf2" <> _ = user.password_hash
+ end
+
+ describe "checkpw/2" do
+ test "check pbkdf2 hash" do
+ hash =
+ "$pbkdf2-sha512$160000$loXqbp8GYls43F0i6lEfIw$AY.Ep.2pGe57j2hAPY635sI/6w7l9Q9u9Bp02PkPmF3OrClDtJAI8bCiivPr53OKMF7ph6iHhN68Rom5nEfC2A"
+
+ assert AuthenticationPlug.checkpw("test-password", hash)
+ refute AuthenticationPlug.checkpw("test-password1", hash)
+ end
+
+ @tag :skip_on_mac
+ test "check sha512-crypt hash" do
+ hash =
+ "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
+
+ assert AuthenticationPlug.checkpw("password", hash)
+ end
+
+ test "check bcrypt hash" do
+ hash = "$2a$10$uyhC/R/zoE1ndwwCtMusK.TLVzkQ/Ugsbqp3uXI.CTTz0gBw.24jS"
+
+ assert AuthenticationPlug.checkpw("password", hash)
+ refute AuthenticationPlug.checkpw("password1", hash)
+ end
+
+ test "it returns false when hash invalid" do
+ hash =
+ "psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
+
+ assert capture_log(fn ->
+ refute Pleroma.Plugs.AuthenticationPlug.checkpw("password", hash)
+ end) =~ "[error] Password hash not recognized"
+ end
+ end
+end
diff --git a/test/pleroma/web/plugs/basic_auth_decoder_plug_test.exs b/test/pleroma/web/plugs/basic_auth_decoder_plug_test.exs
@@ -0,0 +1,35 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.BasicAuthDecoderPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.BasicAuthDecoderPlug
+
+ defp basic_auth_enc(username, password) do
+ "Basic " <> Base.encode64("#{username}:#{password}")
+ end
+
+ test "it puts the decoded credentials into the assigns", %{conn: conn} do
+ header = basic_auth_enc("moonman", "iloverobek")
+
+ conn =
+ conn
+ |> put_req_header("authorization", header)
+ |> BasicAuthDecoderPlug.call(%{})
+
+ assert conn.assigns[:auth_credentials] == %{
+ username: "moonman",
+ password: "iloverobek"
+ }
+ end
+
+ test "without a authorization header it doesn't do anything", %{conn: conn} do
+ ret_conn =
+ conn
+ |> BasicAuthDecoderPlug.call(%{})
+
+ assert conn == ret_conn
+ end
+end
diff --git a/test/pleroma/web/plugs/cache_control_test.exs b/test/pleroma/web/plugs/cache_control_test.exs
@@ -0,0 +1,20 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.CacheControlTest do
+ use Pleroma.Web.ConnCase
+ alias Plug.Conn
+
+ test "Verify Cache-Control header on static assets", %{conn: conn} do
+ conn = get(conn, "/index.html")
+
+ assert Conn.get_resp_header(conn, "cache-control") == ["public, no-cache"]
+ end
+
+ test "Verify Cache-Control header on the API", %{conn: conn} do
+ conn = get(conn, "/api/v1/instance")
+
+ assert Conn.get_resp_header(conn, "cache-control") == ["max-age=0, private, must-revalidate"]
+ end
+end
diff --git a/test/pleroma/web/plugs/cache_test.exs b/test/pleroma/web/plugs/cache_test.exs
@@ -0,0 +1,186 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.CacheTest do
+ use ExUnit.Case, async: true
+ use Plug.Test
+
+ alias Pleroma.Plugs.Cache
+
+ @miss_resp {200,
+ [
+ {"cache-control", "max-age=0, private, must-revalidate"},
+ {"content-type", "cofe/hot; charset=utf-8"},
+ {"x-cache", "MISS from Pleroma"}
+ ], "cofe"}
+
+ @hit_resp {200,
+ [
+ {"cache-control", "max-age=0, private, must-revalidate"},
+ {"content-type", "cofe/hot; charset=utf-8"},
+ {"x-cache", "HIT from Pleroma"}
+ ], "cofe"}
+
+ @ttl 5
+
+ setup do
+ Cachex.clear(:web_resp_cache)
+ :ok
+ end
+
+ test "caches a response" do
+ assert @miss_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+
+ assert_raise(Plug.Conn.AlreadySentError, fn ->
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+ end)
+
+ assert @hit_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> sent_resp()
+ end
+
+ test "ttl is set" do
+ assert @miss_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: @ttl})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+
+ assert @hit_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: @ttl})
+ |> sent_resp()
+
+ :timer.sleep(@ttl + 1)
+
+ assert @miss_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: @ttl})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+ end
+
+ test "set ttl via conn.assigns" do
+ assert @miss_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> assign(:cache_ttl, @ttl)
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+
+ assert @hit_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> sent_resp()
+
+ :timer.sleep(@ttl + 1)
+
+ assert @miss_resp ==
+ conn(:get, "/")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+ end
+
+ test "ignore query string when `query_params` is false" do
+ assert @miss_resp ==
+ conn(:get, "/?cofe")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+
+ assert @hit_resp ==
+ conn(:get, "/?cofefe")
+ |> Cache.call(%{query_params: false, ttl: nil})
+ |> sent_resp()
+ end
+
+ test "take query string into account when `query_params` is true" do
+ assert @miss_resp ==
+ conn(:get, "/?cofe")
+ |> Cache.call(%{query_params: true, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+
+ assert @miss_resp ==
+ conn(:get, "/?cofefe")
+ |> Cache.call(%{query_params: true, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+ end
+
+ test "take specific query params into account when `query_params` is list" do
+ assert @miss_resp ==
+ conn(:get, "/?a=1&b=2&c=3&foo=bar")
+ |> fetch_query_params()
+ |> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+
+ assert @hit_resp ==
+ conn(:get, "/?bar=foo&c=3&b=2&a=1")
+ |> fetch_query_params()
+ |> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
+ |> sent_resp()
+
+ assert @miss_resp ==
+ conn(:get, "/?bar=foo&c=3&b=2&a=2")
+ |> fetch_query_params()
+ |> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+ end
+
+ test "ignore not GET requests" do
+ expected =
+ {200,
+ [
+ {"cache-control", "max-age=0, private, must-revalidate"},
+ {"content-type", "cofe/hot; charset=utf-8"}
+ ], "cofe"}
+
+ assert expected ==
+ conn(:post, "/")
+ |> Cache.call(%{query_params: true, ttl: nil})
+ |> put_resp_content_type("cofe/hot")
+ |> send_resp(:ok, "cofe")
+ |> sent_resp()
+ end
+
+ test "ignore non-successful responses" do
+ expected =
+ {418,
+ [
+ {"cache-control", "max-age=0, private, must-revalidate"},
+ {"content-type", "tea/iced; charset=utf-8"}
+ ], "🥤"}
+
+ assert expected ==
+ conn(:get, "/cofe")
+ |> Cache.call(%{query_params: true, ttl: nil})
+ |> put_resp_content_type("tea/iced")
+ |> send_resp(:im_a_teapot, "🥤")
+ |> sent_resp()
+ end
+end
diff --git a/test/pleroma/web/plugs/ensure_authenticated_plug_test.exs b/test/pleroma/web/plugs/ensure_authenticated_plug_test.exs
@@ -0,0 +1,96 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.EnsureAuthenticatedPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.EnsureAuthenticatedPlug
+ alias Pleroma.User
+
+ describe "without :if_func / :unless_func options" do
+ test "it halts if user is NOT assigned", %{conn: conn} do
+ conn = EnsureAuthenticatedPlug.call(conn, %{})
+
+ assert conn.status == 403
+ assert conn.halted == true
+ end
+
+ test "it continues if a user is assigned", %{conn: conn} do
+ conn = assign(conn, :user, %User{})
+ ret_conn = EnsureAuthenticatedPlug.call(conn, %{})
+
+ refute ret_conn.halted
+ end
+ end
+
+ test "it halts if user is assigned and MFA enabled", %{conn: conn} do
+ conn =
+ conn
+ |> assign(:user, %User{multi_factor_authentication_settings: %{enabled: true}})
+ |> assign(:auth_credentials, %{password: "xd-42"})
+ |> EnsureAuthenticatedPlug.call(%{})
+
+ assert conn.status == 403
+ assert conn.halted == true
+
+ assert conn.resp_body ==
+ "{\"error\":\"Two-factor authentication enabled, you must use a access token.\"}"
+ end
+
+ test "it continues if user is assigned and MFA disabled", %{conn: conn} do
+ conn =
+ conn
+ |> assign(:user, %User{multi_factor_authentication_settings: %{enabled: false}})
+ |> assign(:auth_credentials, %{password: "xd-42"})
+ |> EnsureAuthenticatedPlug.call(%{})
+
+ refute conn.status == 403
+ refute conn.halted
+ end
+
+ describe "with :if_func / :unless_func options" do
+ setup do
+ %{
+ true_fn: fn _conn -> true end,
+ false_fn: fn _conn -> false end
+ }
+ end
+
+ test "it continues if a user is assigned", %{conn: conn, true_fn: true_fn, false_fn: false_fn} do
+ conn = assign(conn, :user, %User{})
+ refute EnsureAuthenticatedPlug.call(conn, if_func: true_fn).halted
+ refute EnsureAuthenticatedPlug.call(conn, if_func: false_fn).halted
+ refute EnsureAuthenticatedPlug.call(conn, unless_func: true_fn).halted
+ refute EnsureAuthenticatedPlug.call(conn, unless_func: false_fn).halted
+ end
+
+ test "it continues if a user is NOT assigned but :if_func evaluates to `false`",
+ %{conn: conn, false_fn: false_fn} do
+ ret_conn = EnsureAuthenticatedPlug.call(conn, if_func: false_fn)
+ refute ret_conn.halted
+ end
+
+ test "it continues if a user is NOT assigned but :unless_func evaluates to `true`",
+ %{conn: conn, true_fn: true_fn} do
+ ret_conn = EnsureAuthenticatedPlug.call(conn, unless_func: true_fn)
+ refute ret_conn.halted
+ end
+
+ test "it halts if a user is NOT assigned and :if_func evaluates to `true`",
+ %{conn: conn, true_fn: true_fn} do
+ conn = EnsureAuthenticatedPlug.call(conn, if_func: true_fn)
+
+ assert conn.status == 403
+ assert conn.halted == true
+ end
+
+ test "it halts if a user is NOT assigned and :unless_func evaluates to `false`",
+ %{conn: conn, false_fn: false_fn} do
+ conn = EnsureAuthenticatedPlug.call(conn, unless_func: false_fn)
+
+ assert conn.status == 403
+ assert conn.halted == true
+ end
+ end
+end
diff --git a/test/pleroma/web/plugs/ensure_public_or_authenticated_plug_test.exs b/test/pleroma/web/plugs/ensure_public_or_authenticated_plug_test.exs
@@ -0,0 +1,48 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Config
+ alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
+ alias Pleroma.User
+
+ setup do: clear_config([:instance, :public])
+
+ test "it halts if not public and no user is assigned", %{conn: conn} do
+ Config.put([:instance, :public], false)
+
+ conn =
+ conn
+ |> EnsurePublicOrAuthenticatedPlug.call(%{})
+
+ assert conn.status == 403
+ assert conn.halted == true
+ end
+
+ test "it continues if public", %{conn: conn} do
+ Config.put([:instance, :public], true)
+
+ ret_conn =
+ conn
+ |> EnsurePublicOrAuthenticatedPlug.call(%{})
+
+ refute ret_conn.halted
+ end
+
+ test "it continues if a user is assigned, even if not public", %{conn: conn} do
+ Config.put([:instance, :public], false)
+
+ conn =
+ conn
+ |> assign(:user, %User{})
+
+ ret_conn =
+ conn
+ |> EnsurePublicOrAuthenticatedPlug.call(%{})
+
+ refute ret_conn.halted
+ end
+end
diff --git a/test/pleroma/web/plugs/ensure_user_key_plug_test.exs b/test/pleroma/web/plugs/ensure_user_key_plug_test.exs
@@ -0,0 +1,29 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.EnsureUserKeyPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.EnsureUserKeyPlug
+
+ test "if the conn has a user key set, it does nothing", %{conn: conn} do
+ conn =
+ conn
+ |> assign(:user, 1)
+
+ ret_conn =
+ conn
+ |> EnsureUserKeyPlug.call(%{})
+
+ assert conn == ret_conn
+ end
+
+ test "if the conn has no key set, it sets it to nil", %{conn: conn} do
+ conn =
+ conn
+ |> EnsureUserKeyPlug.call(%{})
+
+ assert Map.has_key?(conn.assigns, :user)
+ end
+end
diff --git a/test/pleroma/web/plugs/federating_plug_test.exs b/test/pleroma/web/plugs/federating_plug_test.exs
@@ -0,0 +1,31 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.FederatingPlugTest do
+ use Pleroma.Web.ConnCase
+
+ setup do: clear_config([:instance, :federating])
+
+ test "returns and halt the conn when federating is disabled" do
+ Pleroma.Config.put([:instance, :federating], false)
+
+ conn =
+ build_conn()
+ |> Pleroma.Web.FederatingPlug.call(%{})
+
+ assert conn.status == 404
+ assert conn.halted
+ end
+
+ test "does nothing when federating is enabled" do
+ Pleroma.Config.put([:instance, :federating], true)
+
+ conn =
+ build_conn()
+ |> Pleroma.Web.FederatingPlug.call(%{})
+
+ refute conn.status
+ refute conn.halted
+ end
+end
diff --git a/test/plugs/http_security_plug_test.exs b/test/pleroma/web/plugs/http_security_plug_test.exs
diff --git a/test/plugs/http_signature_plug_test.exs b/test/pleroma/web/plugs/http_signature_plug_test.exs
diff --git a/test/pleroma/web/plugs/idempotency_plug_test.exs b/test/pleroma/web/plugs/idempotency_plug_test.exs
@@ -0,0 +1,110 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.IdempotencyPlugTest do
+ use ExUnit.Case, async: true
+ use Plug.Test
+
+ alias Pleroma.Plugs.IdempotencyPlug
+ alias Plug.Conn
+
+ test "returns result from cache" do
+ key = "test1"
+ orig_request_id = "test1"
+ second_request_id = "test2"
+ body = "testing"
+ status = 200
+
+ :post
+ |> conn("/cofe")
+ |> put_req_header("idempotency-key", key)
+ |> Conn.put_resp_header("x-request-id", orig_request_id)
+ |> Conn.put_resp_content_type("application/json")
+ |> IdempotencyPlug.call([])
+ |> Conn.send_resp(status, body)
+
+ conn =
+ :post
+ |> conn("/cofe")
+ |> put_req_header("idempotency-key", key)
+ |> Conn.put_resp_header("x-request-id", second_request_id)
+ |> Conn.put_resp_content_type("application/json")
+ |> IdempotencyPlug.call([])
+
+ assert_raise Conn.AlreadySentError, fn ->
+ Conn.send_resp(conn, :im_a_teapot, "no cofe")
+ end
+
+ assert conn.resp_body == body
+ assert conn.status == status
+
+ assert [^second_request_id] = Conn.get_resp_header(conn, "x-request-id")
+ assert [^orig_request_id] = Conn.get_resp_header(conn, "x-original-request-id")
+ assert [^key] = Conn.get_resp_header(conn, "idempotency-key")
+ assert ["true"] = Conn.get_resp_header(conn, "idempotent-replayed")
+ assert ["application/json; charset=utf-8"] = Conn.get_resp_header(conn, "content-type")
+ end
+
+ test "pass conn downstream if the cache not found" do
+ key = "test2"
+ orig_request_id = "test3"
+ body = "testing"
+ status = 200
+
+ conn =
+ :post
+ |> conn("/cofe")
+ |> put_req_header("idempotency-key", key)
+ |> Conn.put_resp_header("x-request-id", orig_request_id)
+ |> Conn.put_resp_content_type("application/json")
+ |> IdempotencyPlug.call([])
+ |> Conn.send_resp(status, body)
+
+ assert conn.resp_body == body
+ assert conn.status == status
+
+ assert [] = Conn.get_resp_header(conn, "idempotent-replayed")
+ assert [^key] = Conn.get_resp_header(conn, "idempotency-key")
+ end
+
+ test "passes conn downstream if idempotency is not present in headers" do
+ orig_request_id = "test4"
+ body = "testing"
+ status = 200
+
+ conn =
+ :post
+ |> conn("/cofe")
+ |> Conn.put_resp_header("x-request-id", orig_request_id)
+ |> Conn.put_resp_content_type("application/json")
+ |> IdempotencyPlug.call([])
+ |> Conn.send_resp(status, body)
+
+ assert [] = Conn.get_resp_header(conn, "idempotency-key")
+ end
+
+ test "doesn't work with GET/DELETE" do
+ key = "test3"
+ body = "testing"
+ status = 200
+
+ conn =
+ :get
+ |> conn("/cofe")
+ |> put_req_header("idempotency-key", key)
+ |> IdempotencyPlug.call([])
+ |> Conn.send_resp(status, body)
+
+ assert [] = Conn.get_resp_header(conn, "idempotency-key")
+
+ conn =
+ :delete
+ |> conn("/cofe")
+ |> put_req_header("idempotency-key", key)
+ |> IdempotencyPlug.call([])
+ |> Conn.send_resp(status, body)
+
+ assert [] = Conn.get_resp_header(conn, "idempotency-key")
+ end
+end
diff --git a/test/pleroma/web/plugs/instance_static_test.exs b/test/pleroma/web/plugs/instance_static_test.exs
@@ -0,0 +1,65 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.InstanceStaticTest do
+ use Pleroma.Web.ConnCase
+
+ @dir "test/tmp/instance_static"
+
+ setup do
+ File.mkdir_p!(@dir)
+ on_exit(fn -> File.rm_rf(@dir) end)
+ end
+
+ setup do: clear_config([:instance, :static_dir], @dir)
+
+ test "overrides index" do
+ bundled_index = get(build_conn(), "/")
+ refute html_response(bundled_index, 200) == "hello world"
+
+ File.write!(@dir <> "/index.html", "hello world")
+
+ index = get(build_conn(), "/")
+ assert html_response(index, 200) == "hello world"
+ end
+
+ test "also overrides frontend files", %{conn: conn} do
+ name = "pelmora"
+ ref = "uguu"
+
+ clear_config([:frontends, :primary], %{"name" => name, "ref" => ref})
+
+ bundled_index = get(conn, "/")
+ refute html_response(bundled_index, 200) == "from frontend plug"
+
+ path = "#{@dir}/frontends/#{name}/#{ref}"
+ File.mkdir_p!(path)
+ File.write!("#{path}/index.html", "from frontend plug")
+
+ index = get(conn, "/")
+ assert html_response(index, 200) == "from frontend plug"
+
+ File.write!(@dir <> "/index.html", "from instance static")
+
+ index = get(conn, "/")
+ assert html_response(index, 200) == "from instance static"
+ end
+
+ test "overrides any file in static/static" do
+ bundled_index = get(build_conn(), "/static/terms-of-service.html")
+
+ assert html_response(bundled_index, 200) ==
+ File.read!("priv/static/static/terms-of-service.html")
+
+ File.mkdir!(@dir <> "/static")
+ File.write!(@dir <> "/static/terms-of-service.html", "plz be kind")
+
+ index = get(build_conn(), "/static/terms-of-service.html")
+ assert html_response(index, 200) == "plz be kind"
+
+ File.write!(@dir <> "/static/kaniini.html", "<h1>rabbit hugs as a service</h1>")
+ index = get(build_conn(), "/static/kaniini.html")
+ assert html_response(index, 200) == "<h1>rabbit hugs as a service</h1>"
+ end
+end
diff --git a/test/pleroma/web/plugs/legacy_authentication_plug_test.exs b/test/pleroma/web/plugs/legacy_authentication_plug_test.exs
@@ -0,0 +1,82 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.LegacyAuthenticationPlugTest do
+ use Pleroma.Web.ConnCase
+
+ import Pleroma.Factory
+
+ alias Pleroma.Plugs.LegacyAuthenticationPlug
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.Plugs.PlugHelper
+ alias Pleroma.User
+
+ setup do
+ user =
+ insert(:user,
+ password: "password",
+ password_hash:
+ "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
+ )
+
+ %{user: user}
+ end
+
+ test "it does nothing if a user is assigned", %{conn: conn, user: user} do
+ conn =
+ conn
+ |> assign(:auth_credentials, %{username: "dude", password: "password"})
+ |> assign(:auth_user, user)
+ |> assign(:user, %User{})
+
+ ret_conn =
+ conn
+ |> LegacyAuthenticationPlug.call(%{})
+
+ assert ret_conn == conn
+ end
+
+ @tag :skip_on_mac
+ test "if `auth_user` is present and password is correct, " <>
+ "it authenticates the user, resets the password, marks OAuthScopesPlug as skipped",
+ %{
+ conn: conn,
+ user: user
+ } do
+ conn =
+ conn
+ |> assign(:auth_credentials, %{username: "dude", password: "password"})
+ |> assign(:auth_user, user)
+
+ conn = LegacyAuthenticationPlug.call(conn, %{})
+
+ assert conn.assigns.user.id == user.id
+ assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
+ end
+
+ @tag :skip_on_mac
+ test "it does nothing if the password is wrong", %{
+ conn: conn,
+ user: user
+ } do
+ conn =
+ conn
+ |> assign(:auth_credentials, %{username: "dude", password: "wrong_password"})
+ |> assign(:auth_user, user)
+
+ ret_conn =
+ conn
+ |> LegacyAuthenticationPlug.call(%{})
+
+ assert conn == ret_conn
+ end
+
+ test "with no credentials or user it does nothing", %{conn: conn} do
+ ret_conn =
+ conn
+ |> LegacyAuthenticationPlug.call(%{})
+
+ assert ret_conn == conn
+ end
+end
diff --git a/test/plugs/mapped_identity_to_signature_plug_test.exs b/test/pleroma/web/plugs/mapped_signature_to_identity_plug_test.exs
diff --git a/test/pleroma/web/plugs/o_auth_plug_test.exs b/test/pleroma/web/plugs/o_auth_plug_test.exs
@@ -0,0 +1,80 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.OAuthPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.OAuthPlug
+ import Pleroma.Factory
+
+ @session_opts [
+ store: :cookie,
+ key: "_test",
+ signing_salt: "cooldude"
+ ]
+
+ setup %{conn: conn} do
+ user = insert(:user)
+ {:ok, %{token: token}} = Pleroma.Web.OAuth.Token.create(insert(:oauth_app), user)
+ %{user: user, token: token, conn: conn}
+ end
+
+ test "with valid token(uppercase), it assigns the user", %{conn: conn} = opts do
+ conn =
+ conn
+ |> put_req_header("authorization", "BEARER #{opts[:token]}")
+ |> OAuthPlug.call(%{})
+
+ assert conn.assigns[:user] == opts[:user]
+ end
+
+ test "with valid token(downcase), it assigns the user", %{conn: conn} = opts do
+ conn =
+ conn
+ |> put_req_header("authorization", "bearer #{opts[:token]}")
+ |> OAuthPlug.call(%{})
+
+ assert conn.assigns[:user] == opts[:user]
+ end
+
+ test "with valid token(downcase) in url parameters, it assigns the user", opts do
+ conn =
+ :get
+ |> build_conn("/?access_token=#{opts[:token]}")
+ |> put_req_header("content-type", "application/json")
+ |> fetch_query_params()
+ |> OAuthPlug.call(%{})
+
+ assert conn.assigns[:user] == opts[:user]
+ end
+
+ test "with valid token(downcase) in body parameters, it assigns the user", opts do
+ conn =
+ :post
+ |> build_conn("/api/v1/statuses", access_token: opts[:token], status: "test")
+ |> OAuthPlug.call(%{})
+
+ assert conn.assigns[:user] == opts[:user]
+ end
+
+ test "with invalid token, it not assigns the user", %{conn: conn} do
+ conn =
+ conn
+ |> put_req_header("authorization", "bearer TTTTT")
+ |> OAuthPlug.call(%{})
+
+ refute conn.assigns[:user]
+ end
+
+ test "when token is missed but token in session, it assigns the user", %{conn: conn} = opts do
+ conn =
+ conn
+ |> Plug.Session.call(Plug.Session.init(@session_opts))
+ |> fetch_session()
+ |> put_session(:oauth_token, opts[:token])
+ |> OAuthPlug.call(%{})
+
+ assert conn.assigns[:user] == opts[:user]
+ end
+end
diff --git a/test/pleroma/web/plugs/o_auth_scopes_plug_test.exs b/test/pleroma/web/plugs/o_auth_scopes_plug_test.exs
@@ -0,0 +1,210 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.OAuthScopesPlugTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.Repo
+
+ import Mock
+ import Pleroma.Factory
+
+ test "is not performed if marked as skipped", %{conn: conn} do
+ with_mock OAuthScopesPlug, [:passthrough], perform: &passthrough([&1, &2]) do
+ conn =
+ conn
+ |> OAuthScopesPlug.skip_plug()
+ |> OAuthScopesPlug.call(%{scopes: ["random_scope"]})
+
+ refute called(OAuthScopesPlug.perform(:_, :_))
+ refute conn.halted
+ end
+ end
+
+ test "if `token.scopes` fulfills specified 'any of' conditions, " <>
+ "proceeds with no op",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: ["read"]})
+
+ refute conn.halted
+ assert conn.assigns[:user]
+ end
+
+ test "if `token.scopes` fulfills specified 'all of' conditions, " <>
+ "proceeds with no op",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: ["scope2", "scope3"], op: :&})
+
+ refute conn.halted
+ assert conn.assigns[:user]
+ end
+
+ describe "with `fallback: :proceed_unauthenticated` option, " do
+ test "if `token.scopes` doesn't fulfill specified conditions, " <>
+ "clears :user and :token assigns",
+ %{conn: conn} do
+ user = insert(:user)
+ token1 = insert(:oauth_token, scopes: ["read", "write"], user: user)
+
+ for token <- [token1, nil], op <- [:|, :&] do
+ ret_conn =
+ conn
+ |> assign(:user, user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{
+ scopes: ["follow"],
+ op: op,
+ fallback: :proceed_unauthenticated
+ })
+
+ refute ret_conn.halted
+ refute ret_conn.assigns[:user]
+ refute ret_conn.assigns[:token]
+ end
+ end
+ end
+
+ describe "without :fallback option, " do
+ test "if `token.scopes` does not fulfill specified 'any of' conditions, " <>
+ "returns 403 and halts",
+ %{conn: conn} do
+ for token <- [insert(:oauth_token, scopes: ["read", "write"]), nil] do
+ any_of_scopes = ["follow", "push"]
+
+ ret_conn =
+ conn
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: any_of_scopes})
+
+ assert ret_conn.halted
+ assert 403 == ret_conn.status
+
+ expected_error = "Insufficient permissions: #{Enum.join(any_of_scopes, " | ")}."
+ assert Jason.encode!(%{error: expected_error}) == ret_conn.resp_body
+ end
+ end
+
+ test "if `token.scopes` does not fulfill specified 'all of' conditions, " <>
+ "returns 403 and halts",
+ %{conn: conn} do
+ for token <- [insert(:oauth_token, scopes: ["read", "write"]), nil] do
+ token_scopes = (token && token.scopes) || []
+ all_of_scopes = ["write", "follow"]
+
+ conn =
+ conn
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: all_of_scopes, op: :&})
+
+ assert conn.halted
+ assert 403 == conn.status
+
+ expected_error =
+ "Insufficient permissions: #{Enum.join(all_of_scopes -- token_scopes, " & ")}."
+
+ assert Jason.encode!(%{error: expected_error}) == conn.resp_body
+ end
+ end
+ end
+
+ describe "with hierarchical scopes, " do
+ test "if `token.scopes` fulfills specified 'any of' conditions, " <>
+ "proceeds with no op",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: ["read:something"]})
+
+ refute conn.halted
+ assert conn.assigns[:user]
+ end
+
+ test "if `token.scopes` fulfills specified 'all of' conditions, " <>
+ "proceeds with no op",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: ["scope1:subscope", "scope2:subscope"], op: :&})
+
+ refute conn.halted
+ assert conn.assigns[:user]
+ end
+ end
+
+ describe "filter_descendants/2" do
+ test "filters scopes which directly match or are ancestors of supported scopes" do
+ f = fn scopes, supported_scopes ->
+ OAuthScopesPlug.filter_descendants(scopes, supported_scopes)
+ end
+
+ assert f.(["read", "follow"], ["write", "read"]) == ["read"]
+
+ assert f.(["read", "write:something", "follow"], ["write", "read"]) ==
+ ["read", "write:something"]
+
+ assert f.(["admin:read"], ["write", "read"]) == []
+
+ assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"]
+ end
+ end
+
+ describe "transform_scopes/2" do
+ setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage])
+
+ setup do
+ {:ok, %{f: &OAuthScopesPlug.transform_scopes/2}}
+ end
+
+ test "with :admin option, prefixes all requested scopes with `admin:` " <>
+ "and [optionally] keeps only prefixed scopes, " <>
+ "depending on `[:auth, :enforce_oauth_admin_scope_usage]` setting",
+ %{f: f} do
+ Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
+
+ assert f.(["read"], %{admin: true}) == ["admin:read", "read"]
+
+ assert f.(["read", "write"], %{admin: true}) == [
+ "admin:read",
+ "read",
+ "admin:write",
+ "write"
+ ]
+
+ Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
+
+ assert f.(["read:accounts"], %{admin: true}) == ["admin:read:accounts"]
+
+ assert f.(["read", "write:reports"], %{admin: true}) == [
+ "admin:read",
+ "admin:write:reports"
+ ]
+ end
+
+ test "with no supported options, returns unmodified scopes", %{f: f} do
+ assert f.(["read"], %{}) == ["read"]
+ assert f.(["read", "write"], %{}) == ["read", "write"]
+ end
+ end
+end
diff --git a/test/pleroma/web/plugs/plug_helper_test.exs b/test/pleroma/web/plugs/plug_helper_test.exs
@@ -0,0 +1,91 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.PlugHelperTest do
+ @moduledoc "Tests for the functionality added via `use Pleroma.Web, :plug`"
+
+ alias Pleroma.Plugs.ExpectAuthenticatedCheckPlug
+ alias Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug
+ alias Pleroma.Plugs.PlugHelper
+
+ import Mock
+
+ use Pleroma.Web.ConnCase
+
+ describe "when plug is skipped, " do
+ setup_with_mocks(
+ [
+ {ExpectPublicOrAuthenticatedCheckPlug, [:passthrough], []}
+ ],
+ %{conn: conn}
+ ) do
+ conn = ExpectPublicOrAuthenticatedCheckPlug.skip_plug(conn)
+ %{conn: conn}
+ end
+
+ test "it neither adds plug to called plugs list nor calls `perform/2`, " <>
+ "regardless of :if_func / :unless_func options",
+ %{conn: conn} do
+ for opts <- [%{}, %{if_func: fn _ -> true end}, %{unless_func: fn _ -> false end}] do
+ ret_conn = ExpectPublicOrAuthenticatedCheckPlug.call(conn, opts)
+
+ refute called(ExpectPublicOrAuthenticatedCheckPlug.perform(:_, :_))
+ refute PlugHelper.plug_called?(ret_conn, ExpectPublicOrAuthenticatedCheckPlug)
+ end
+ end
+ end
+
+ describe "when plug is NOT skipped, " do
+ setup_with_mocks([{ExpectAuthenticatedCheckPlug, [:passthrough], []}]) do
+ :ok
+ end
+
+ test "with no pre-run checks, adds plug to called plugs list and calls `perform/2`", %{
+ conn: conn
+ } do
+ ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{})
+
+ assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
+ assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
+ end
+
+ test "when :if_func option is given, calls the plug only if provided function evals tru-ish",
+ %{conn: conn} do
+ ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{if_func: fn _ -> false end})
+
+ refute called(ExpectAuthenticatedCheckPlug.perform(:_, :_))
+ refute PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
+
+ ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{if_func: fn _ -> true end})
+
+ assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
+ assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
+ end
+
+ test "if :unless_func option is given, calls the plug only if provided function evals falsy",
+ %{conn: conn} do
+ ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{unless_func: fn _ -> true end})
+
+ refute called(ExpectAuthenticatedCheckPlug.perform(:_, :_))
+ refute PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
+
+ ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{unless_func: fn _ -> false end})
+
+ assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
+ assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
+ end
+
+ test "allows a plug to be called multiple times (even if it's in called plugs list)", %{
+ conn: conn
+ } do
+ conn = ExpectAuthenticatedCheckPlug.call(conn, %{an_option: :value1})
+ assert called(ExpectAuthenticatedCheckPlug.perform(conn, %{an_option: :value1}))
+
+ assert PlugHelper.plug_called?(conn, ExpectAuthenticatedCheckPlug)
+
+ conn = ExpectAuthenticatedCheckPlug.call(conn, %{an_option: :value2})
+ assert called(ExpectAuthenticatedCheckPlug.perform(conn, %{an_option: :value2}))
+ end
+ end
+end
diff --git a/test/pleroma/web/plugs/rate_limiter_test.exs b/test/pleroma/web/plugs/rate_limiter_test.exs
@@ -0,0 +1,263 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.RateLimiterTest do
+ use Pleroma.Web.ConnCase
+
+ alias Phoenix.ConnTest
+ alias Pleroma.Config
+ alias Pleroma.Plugs.RateLimiter
+ alias Plug.Conn
+
+ import Pleroma.Factory
+ import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
+
+ # Note: each example must work with separate buckets in order to prevent concurrency issues
+ setup do: clear_config([Pleroma.Web.Endpoint, :http, :ip])
+ setup do: clear_config(:rate_limit)
+
+ describe "config" do
+ @limiter_name :test_init
+ setup do: clear_config([Pleroma.Plugs.RemoteIp, :enabled])
+
+ test "config is required for plug to work" do
+ Config.put([:rate_limit, @limiter_name], {1, 1})
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+
+ assert %{limits: {1, 1}, name: :test_init, opts: [name: :test_init]} ==
+ [name: @limiter_name]
+ |> RateLimiter.init()
+ |> RateLimiter.action_settings()
+
+ assert nil ==
+ [name: :nonexisting_limiter]
+ |> RateLimiter.init()
+ |> RateLimiter.action_settings()
+ end
+ end
+
+ test "it is disabled if it remote ip plug is enabled but no remote ip is found" do
+ assert RateLimiter.disabled?(Conn.assign(build_conn(), :remote_ip_found, false))
+ end
+
+ test "it is enabled if remote ip found" do
+ refute RateLimiter.disabled?(Conn.assign(build_conn(), :remote_ip_found, true))
+ end
+
+ test "it is enabled if remote_ip_found flag doesn't exist" do
+ refute RateLimiter.disabled?(build_conn())
+ end
+
+ test "it restricts based on config values" do
+ limiter_name = :test_plug_opts
+ scale = 80
+ limit = 5
+
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+ Config.put([:rate_limit, limiter_name], {scale, limit})
+
+ plug_opts = RateLimiter.init(name: limiter_name)
+ conn = build_conn(:get, "/")
+
+ for i <- 1..5 do
+ conn = RateLimiter.call(conn, plug_opts)
+ assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+ Process.sleep(10)
+ end
+
+ conn = RateLimiter.call(conn, plug_opts)
+ assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
+ assert conn.halted
+
+ Process.sleep(50)
+
+ conn = build_conn(:get, "/")
+
+ conn = RateLimiter.call(conn, plug_opts)
+ assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+
+ refute conn.status == Conn.Status.code(:too_many_requests)
+ refute conn.resp_body
+ refute conn.halted
+ end
+
+ describe "options" do
+ test "`bucket_name` option overrides default bucket name" do
+ limiter_name = :test_bucket_name
+
+ Config.put([:rate_limit, limiter_name], {1000, 5})
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+
+ base_bucket_name = "#{limiter_name}:group1"
+ plug_opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name)
+
+ conn = build_conn(:get, "/")
+
+ RateLimiter.call(conn, plug_opts)
+ assert {1, 4} = RateLimiter.inspect_bucket(conn, base_bucket_name, plug_opts)
+ assert {:error, :not_found} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+ end
+
+ test "`params` option allows different queries to be tracked independently" do
+ limiter_name = :test_params
+ Config.put([:rate_limit, limiter_name], {1000, 5})
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+
+ plug_opts = RateLimiter.init(name: limiter_name, params: ["id"])
+
+ conn = build_conn(:get, "/?id=1")
+ conn = Conn.fetch_query_params(conn)
+ conn_2 = build_conn(:get, "/?id=2")
+
+ RateLimiter.call(conn, plug_opts)
+ assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+ assert {0, 5} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
+ end
+
+ test "it supports combination of options modifying bucket name" do
+ limiter_name = :test_options_combo
+ Config.put([:rate_limit, limiter_name], {1000, 5})
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+
+ base_bucket_name = "#{limiter_name}:group1"
+
+ plug_opts =
+ RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name, params: ["id"])
+
+ id = "100"
+
+ conn = build_conn(:get, "/?id=#{id}")
+ conn = Conn.fetch_query_params(conn)
+ conn_2 = build_conn(:get, "/?id=#{101}")
+
+ RateLimiter.call(conn, plug_opts)
+ assert {1, 4} = RateLimiter.inspect_bucket(conn, base_bucket_name, plug_opts)
+ assert {0, 5} = RateLimiter.inspect_bucket(conn_2, base_bucket_name, plug_opts)
+ end
+ end
+
+ describe "unauthenticated users" do
+ test "are restricted based on remote IP" do
+ limiter_name = :test_unauthenticated
+ Config.put([:rate_limit, limiter_name], [{1000, 5}, {1, 10}])
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+
+ plug_opts = RateLimiter.init(name: limiter_name)
+
+ conn = %{build_conn(:get, "/") | remote_ip: {127, 0, 0, 2}}
+ conn_2 = %{build_conn(:get, "/") | remote_ip: {127, 0, 0, 3}}
+
+ for i <- 1..5 do
+ conn = RateLimiter.call(conn, plug_opts)
+ assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+ refute conn.halted
+ end
+
+ conn = RateLimiter.call(conn, plug_opts)
+
+ assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
+ assert conn.halted
+
+ conn_2 = RateLimiter.call(conn_2, plug_opts)
+ assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
+
+ refute conn_2.status == Conn.Status.code(:too_many_requests)
+ refute conn_2.resp_body
+ refute conn_2.halted
+ end
+ end
+
+ describe "authenticated users" do
+ setup do
+ Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo)
+
+ :ok
+ end
+
+ test "can have limits separate from unauthenticated connections" do
+ limiter_name = :test_authenticated1
+
+ scale = 50
+ limit = 5
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+ Config.put([:rate_limit, limiter_name], [{1000, 1}, {scale, limit}])
+
+ plug_opts = RateLimiter.init(name: limiter_name)
+
+ user = insert(:user)
+ conn = build_conn(:get, "/") |> assign(:user, user)
+
+ for i <- 1..5 do
+ conn = RateLimiter.call(conn, plug_opts)
+ assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+ refute conn.halted
+ end
+
+ conn = RateLimiter.call(conn, plug_opts)
+
+ assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
+ assert conn.halted
+ end
+
+ test "different users are counted independently" do
+ limiter_name = :test_authenticated2
+ Config.put([:rate_limit, limiter_name], [{1, 10}, {1000, 5}])
+ Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+
+ plug_opts = RateLimiter.init(name: limiter_name)
+
+ user = insert(:user)
+ conn = build_conn(:get, "/") |> assign(:user, user)
+
+ user_2 = insert(:user)
+ conn_2 = build_conn(:get, "/") |> assign(:user, user_2)
+
+ for i <- 1..5 do
+ conn = RateLimiter.call(conn, plug_opts)
+ assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
+ end
+
+ conn = RateLimiter.call(conn, plug_opts)
+ assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
+ assert conn.halted
+
+ conn_2 = RateLimiter.call(conn_2, plug_opts)
+ assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
+ refute conn_2.status == Conn.Status.code(:too_many_requests)
+ refute conn_2.resp_body
+ refute conn_2.halted
+ end
+ end
+
+ test "doesn't crash due to a race condition when multiple requests are made at the same time and the bucket is not yet initialized" do
+ limiter_name = :test_race_condition
+ Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
+ Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
+
+ opts = RateLimiter.init(name: limiter_name)
+
+ conn = build_conn(:get, "/")
+ conn_2 = build_conn(:get, "/")
+
+ %Task{pid: pid1} =
+ task1 =
+ Task.async(fn ->
+ receive do
+ :process2_up ->
+ RateLimiter.call(conn, opts)
+ end
+ end)
+
+ task2 =
+ Task.async(fn ->
+ send(pid1, :process2_up)
+ RateLimiter.call(conn_2, opts)
+ end)
+
+ Task.await(task1)
+ Task.await(task2)
+
+ refute {:err, :not_found} == RateLimiter.inspect_bucket(conn, limiter_name, opts)
+ end
+end
diff --git a/test/pleroma/web/plugs/remote_ip_test.exs b/test/pleroma/web/plugs/remote_ip_test.exs
@@ -0,0 +1,108 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.RemoteIpTest do
+ use ExUnit.Case
+ use Plug.Test
+
+ alias Pleroma.Plugs.RemoteIp
+
+ import Pleroma.Tests.Helpers, only: [clear_config: 2]
+
+ setup do:
+ clear_config(RemoteIp,
+ enabled: true,
+ headers: ["x-forwarded-for"],
+ proxies: [],
+ reserved: [
+ "127.0.0.0/8",
+ "::1/128",
+ "fc00::/7",
+ "10.0.0.0/8",
+ "172.16.0.0/12",
+ "192.168.0.0/16"
+ ]
+ )
+
+ test "disabled" do
+ Pleroma.Config.put(RemoteIp, enabled: false)
+
+ %{remote_ip: remote_ip} = conn(:get, "/")
+
+ conn =
+ conn(:get, "/")
+ |> put_req_header("x-forwarded-for", "1.1.1.1")
+ |> RemoteIp.call(nil)
+
+ assert conn.remote_ip == remote_ip
+ end
+
+ test "enabled" do
+ conn =
+ conn(:get, "/")
+ |> put_req_header("x-forwarded-for", "1.1.1.1")
+ |> RemoteIp.call(nil)
+
+ assert conn.remote_ip == {1, 1, 1, 1}
+ end
+
+ test "custom headers" do
+ Pleroma.Config.put(RemoteIp, enabled: true, headers: ["cf-connecting-ip"])
+
+ conn =
+ conn(:get, "/")
+ |> put_req_header("x-forwarded-for", "1.1.1.1")
+ |> RemoteIp.call(nil)
+
+ refute conn.remote_ip == {1, 1, 1, 1}
+
+ conn =
+ conn(:get, "/")
+ |> put_req_header("cf-connecting-ip", "1.1.1.1")
+ |> RemoteIp.call(nil)
+
+ assert conn.remote_ip == {1, 1, 1, 1}
+ end
+
+ test "custom proxies" do
+ conn =
+ conn(:get, "/")
+ |> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1, 173.245.48.2")
+ |> RemoteIp.call(nil)
+
+ refute conn.remote_ip == {1, 1, 1, 1}
+
+ Pleroma.Config.put([RemoteIp, :proxies], ["173.245.48.0/20"])
+
+ conn =
+ conn(:get, "/")
+ |> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1, 173.245.48.2")
+ |> RemoteIp.call(nil)
+
+ assert conn.remote_ip == {1, 1, 1, 1}
+ end
+
+ test "proxies set without CIDR format" do
+ Pleroma.Config.put([RemoteIp, :proxies], ["173.245.48.1"])
+
+ conn =
+ conn(:get, "/")
+ |> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1")
+ |> RemoteIp.call(nil)
+
+ assert conn.remote_ip == {1, 1, 1, 1}
+ end
+
+ test "proxies set `nonsensical` CIDR" do
+ Pleroma.Config.put([RemoteIp, :reserved], ["127.0.0.0/8"])
+ Pleroma.Config.put([RemoteIp, :proxies], ["10.0.0.3/24"])
+
+ conn =
+ conn(:get, "/")
+ |> put_req_header("x-forwarded-for", "10.0.0.3, 1.1.1.1")
+ |> RemoteIp.call(nil)
+
+ assert conn.remote_ip == {1, 1, 1, 1}
+ end
+end
diff --git a/test/pleroma/web/plugs/session_authentication_plug_test.exs b/test/pleroma/web/plugs/session_authentication_plug_test.exs
@@ -0,0 +1,63 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.SessionAuthenticationPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.SessionAuthenticationPlug
+ alias Pleroma.User
+
+ setup %{conn: conn} do
+ session_opts = [
+ store: :cookie,
+ key: "_test",
+ signing_salt: "cooldude"
+ ]
+
+ conn =
+ conn
+ |> Plug.Session.call(Plug.Session.init(session_opts))
+ |> fetch_session
+ |> assign(:auth_user, %User{id: 1})
+
+ %{conn: conn}
+ end
+
+ test "it does nothing if a user is assigned", %{conn: conn} do
+ conn =
+ conn
+ |> assign(:user, %User{})
+
+ ret_conn =
+ conn
+ |> SessionAuthenticationPlug.call(%{})
+
+ assert ret_conn == conn
+ end
+
+ test "if the auth_user has the same id as the user_id in the session, it assigns the user", %{
+ conn: conn
+ } do
+ conn =
+ conn
+ |> put_session(:user_id, conn.assigns.auth_user.id)
+ |> SessionAuthenticationPlug.call(%{})
+
+ assert conn.assigns.user == conn.assigns.auth_user
+ end
+
+ test "if the auth_user has a different id as the user_id in the session, it does nothing", %{
+ conn: conn
+ } do
+ conn =
+ conn
+ |> put_session(:user_id, -1)
+
+ ret_conn =
+ conn
+ |> SessionAuthenticationPlug.call(%{})
+
+ assert ret_conn == conn
+ end
+end
diff --git a/test/pleroma/web/plugs/set_format_plug_test.exs b/test/pleroma/web/plugs/set_format_plug_test.exs
@@ -0,0 +1,38 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.SetFormatPlugTest do
+ use ExUnit.Case, async: true
+ use Plug.Test
+
+ alias Pleroma.Plugs.SetFormatPlug
+
+ test "set format from params" do
+ conn =
+ :get
+ |> conn("/cofe?_format=json")
+ |> SetFormatPlug.call([])
+
+ assert %{format: "json"} == conn.assigns
+ end
+
+ test "set format from header" do
+ conn =
+ :get
+ |> conn("/cofe")
+ |> put_private(:phoenix_format, "xml")
+ |> SetFormatPlug.call([])
+
+ assert %{format: "xml"} == conn.assigns
+ end
+
+ test "doesn't set format" do
+ conn =
+ :get
+ |> conn("/cofe")
+ |> SetFormatPlug.call([])
+
+ refute conn.assigns[:format]
+ end
+end
diff --git a/test/pleroma/web/plugs/set_locale_plug_test.exs b/test/pleroma/web/plugs/set_locale_plug_test.exs
@@ -0,0 +1,46 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.SetLocalePlugTest do
+ use ExUnit.Case, async: true
+ use Plug.Test
+
+ alias Pleroma.Plugs.SetLocalePlug
+ alias Plug.Conn
+
+ test "default locale is `en`" do
+ conn =
+ :get
+ |> conn("/cofe")
+ |> SetLocalePlug.call([])
+
+ assert "en" == Gettext.get_locale()
+ assert %{locale: "en"} == conn.assigns
+ end
+
+ test "use supported locale from `accept-language`" do
+ conn =
+ :get
+ |> conn("/cofe")
+ |> Conn.put_req_header(
+ "accept-language",
+ "ru, fr-CH, fr;q=0.9, en;q=0.8, *;q=0.5"
+ )
+ |> SetLocalePlug.call([])
+
+ assert "ru" == Gettext.get_locale()
+ assert %{locale: "ru"} == conn.assigns
+ end
+
+ test "use default locale if locale from `accept-language` is not supported" do
+ conn =
+ :get
+ |> conn("/cofe")
+ |> Conn.put_req_header("accept-language", "tlh")
+ |> SetLocalePlug.call([])
+
+ assert "en" == Gettext.get_locale()
+ assert %{locale: "en"} == conn.assigns
+ end
+end
diff --git a/test/pleroma/web/plugs/set_user_session_id_plug_test.exs b/test/pleroma/web/plugs/set_user_session_id_plug_test.exs
@@ -0,0 +1,45 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.SetUserSessionIdPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.SetUserSessionIdPlug
+ alias Pleroma.User
+
+ setup %{conn: conn} do
+ session_opts = [
+ store: :cookie,
+ key: "_test",
+ signing_salt: "cooldude"
+ ]
+
+ conn =
+ conn
+ |> Plug.Session.call(Plug.Session.init(session_opts))
+ |> fetch_session
+
+ %{conn: conn}
+ end
+
+ test "doesn't do anything if the user isn't set", %{conn: conn} do
+ ret_conn =
+ conn
+ |> SetUserSessionIdPlug.call(%{})
+
+ assert ret_conn == conn
+ end
+
+ test "sets the user_id in the session to the user id of the user assign", %{conn: conn} do
+ Code.ensure_compiled(Pleroma.User)
+
+ conn =
+ conn
+ |> assign(:user, %User{id: 1})
+ |> SetUserSessionIdPlug.call(%{})
+
+ id = get_session(conn, :user_id)
+ assert id == 1
+ end
+end
diff --git a/test/pleroma/web/plugs/uploaded_media_plug_test.exs b/test/pleroma/web/plugs/uploaded_media_plug_test.exs
@@ -0,0 +1,43 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.UploadedMediaPlugTest do
+ use Pleroma.Web.ConnCase
+ alias Pleroma.Upload
+
+ defp upload_file(context) do
+ Pleroma.DataCase.ensure_local_uploader(context)
+ File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
+
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image_tmp.jpg"),
+ filename: "nice_tf.jpg"
+ }
+
+ {:ok, data} = Upload.store(file)
+ [%{"href" => attachment_url} | _] = data["url"]
+ [attachment_url: attachment_url]
+ end
+
+ setup_all :upload_file
+
+ test "does not send Content-Disposition header when name param is not set", %{
+ attachment_url: attachment_url
+ } do
+ conn = get(build_conn(), attachment_url)
+ refute Enum.any?(conn.resp_headers, &(elem(&1, 0) == "content-disposition"))
+ end
+
+ test "sends Content-Disposition header when name param is set", %{
+ attachment_url: attachment_url
+ } do
+ conn = get(build_conn(), attachment_url <> "?name=\"cofe\".gif")
+
+ assert Enum.any?(
+ conn.resp_headers,
+ &(&1 == {"content-disposition", "filename=\"\\\"cofe\\\".gif\""})
+ )
+ end
+end
diff --git a/test/pleroma/web/plugs/user_enabled_plug_test.exs b/test/pleroma/web/plugs/user_enabled_plug_test.exs
@@ -0,0 +1,59 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.UserEnabledPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.UserEnabledPlug
+ import Pleroma.Factory
+
+ setup do: clear_config([:instance, :account_activation_required])
+
+ test "doesn't do anything if the user isn't set", %{conn: conn} do
+ ret_conn =
+ conn
+ |> UserEnabledPlug.call(%{})
+
+ assert ret_conn == conn
+ end
+
+ test "with a user that's not confirmed and a config requiring confirmation, it removes that user",
+ %{conn: conn} do
+ Pleroma.Config.put([:instance, :account_activation_required], true)
+
+ user = insert(:user, confirmation_pending: true)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> UserEnabledPlug.call(%{})
+
+ assert conn.assigns.user == nil
+ end
+
+ test "with a user that is deactivated, it removes that user", %{conn: conn} do
+ user = insert(:user, deactivated: true)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> UserEnabledPlug.call(%{})
+
+ assert conn.assigns.user == nil
+ end
+
+ test "with a user that is not deactivated, it does nothing", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+
+ ret_conn =
+ conn
+ |> UserEnabledPlug.call(%{})
+
+ assert conn == ret_conn
+ end
+end
diff --git a/test/pleroma/web/plugs/user_fetcher_plug_test.exs b/test/pleroma/web/plugs/user_fetcher_plug_test.exs
@@ -0,0 +1,41 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.UserFetcherPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.UserFetcherPlug
+ import Pleroma.Factory
+
+ setup do
+ user = insert(:user)
+ %{user: user}
+ end
+
+ test "if an auth_credentials assign is present, it tries to fetch the user and assigns it", %{
+ conn: conn,
+ user: user
+ } do
+ conn =
+ conn
+ |> assign(:auth_credentials, %{
+ username: user.nickname,
+ password: nil
+ })
+
+ conn =
+ conn
+ |> UserFetcherPlug.call(%{})
+
+ assert conn.assigns[:auth_user] == user
+ end
+
+ test "without a credential assign it doesn't do anything", %{conn: conn} do
+ ret_conn =
+ conn
+ |> UserFetcherPlug.call(%{})
+
+ assert conn == ret_conn
+ end
+end
diff --git a/test/pleroma/web/plugs/user_is_admin_plug_test.exs b/test/pleroma/web/plugs/user_is_admin_plug_test.exs
@@ -0,0 +1,37 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.UserIsAdminPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.UserIsAdminPlug
+ import Pleroma.Factory
+
+ test "accepts a user that is an admin" do
+ user = insert(:user, is_admin: true)
+
+ conn = assign(build_conn(), :user, user)
+
+ ret_conn = UserIsAdminPlug.call(conn, %{})
+
+ assert conn == ret_conn
+ end
+
+ test "denies a user that isn't an admin" do
+ user = insert(:user)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> UserIsAdminPlug.call(%{})
+
+ assert conn.status == 403
+ end
+
+ test "denies when a user isn't set" do
+ conn = UserIsAdminPlug.call(build_conn(), %{})
+
+ assert conn.status == 403
+ end
+end
diff --git a/test/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs
diff --git a/test/web/rel_me_test.exs b/test/pleroma/web/rel_me_test.exs
diff --git a/test/web/rich_media/helpers_test.exs b/test/pleroma/web/rich_media/helpers_test.exs
diff --git a/test/web/rich_media/parser_test.exs b/test/pleroma/web/rich_media/parser_test.exs
diff --git a/test/pleroma/web/rich_media/parsers/ttl/aws_signed_url_test.exs b/test/pleroma/web/rich_media/parsers/ttl/aws_signed_url_test.exs
@@ -0,0 +1,82 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.RichMedia.Parsers.TTL.AwsSignedUrlTest do
+ use ExUnit.Case, async: true
+
+ test "s3 signed url is parsed correct for expiration time" do
+ url = "https://pleroma.social/amz"
+
+ {:ok, timestamp} =
+ Timex.now()
+ |> DateTime.truncate(:second)
+ |> Timex.format("{ISO:Basic:Z}")
+
+ # in seconds
+ valid_till = 30
+
+ metadata = construct_metadata(timestamp, valid_till, url)
+
+ expire_time =
+ Timex.parse!(timestamp, "{ISO:Basic:Z}") |> Timex.to_unix() |> Kernel.+(valid_till)
+
+ assert {:ok, expire_time} == Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl.ttl(metadata, url)
+ end
+
+ test "s3 signed url is parsed and correct ttl is set for rich media" do
+ url = "https://pleroma.social/amz"
+
+ {:ok, timestamp} =
+ Timex.now()
+ |> DateTime.truncate(:second)
+ |> Timex.format("{ISO:Basic:Z}")
+
+ # in seconds
+ valid_till = 30
+
+ metadata = construct_metadata(timestamp, valid_till, url)
+
+ body = """
+ <meta name="twitter:card" content="Pleroma" />
+ <meta name="twitter:site" content="Pleroma" />
+ <meta name="twitter:title" content="Pleroma" />
+ <meta name="twitter:description" content="Pleroma" />
+ <meta name="twitter:image" content="#{Map.get(metadata, :image)}" />
+ """
+
+ Tesla.Mock.mock(fn
+ %{
+ method: :get,
+ url: "https://pleroma.social/amz"
+ } ->
+ %Tesla.Env{status: 200, body: body}
+ end)
+
+ Cachex.put(:rich_media_cache, url, metadata)
+
+ Pleroma.Web.RichMedia.Parser.set_ttl_based_on_image(metadata, url)
+
+ {:ok, cache_ttl} = Cachex.ttl(:rich_media_cache, url)
+
+ # as there is delay in setting and pulling the data from cache we ignore 1 second
+ # make it 2 seconds for flakyness
+ assert_in_delta(valid_till * 1000, cache_ttl, 2000)
+ end
+
+ defp construct_s3_url(timestamp, valid_till) do
+ "https://pleroma.s3.ap-southeast-1.amazonaws.com/sachin%20%281%29%20_a%20-%25%2Aasdasd%20BNN%20bnnn%20.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIBLWWK6RGDQXDLJQ%2F20190716%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=#{
+ timestamp
+ }&X-Amz-Expires=#{valid_till}&X-Amz-Signature=04ffd6b98634f4b1bbabc62e0fac4879093cd54a6eed24fe8eb38e8369526bbf&X-Amz-SignedHeaders=host"
+ end
+
+ defp construct_metadata(timestamp, valid_till, url) do
+ %{
+ image: construct_s3_url(timestamp, valid_till),
+ site: "Pleroma",
+ title: "Pleroma",
+ description: "Pleroma",
+ url: url
+ }
+ end
+end
diff --git a/test/web/rich_media/parsers/twitter_card_test.exs b/test/pleroma/web/rich_media/parsers/twitter_card_test.exs
diff --git a/test/web/static_fe/static_fe_controller_test.exs b/test/pleroma/web/static_fe/static_fe_controller_test.exs
diff --git a/test/web/streamer/streamer_test.exs b/test/pleroma/web/streamer_test.exs
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/pleroma/web/twitter_api/controller_test.exs
diff --git a/test/web/twitter_api/password_controller_test.exs b/test/pleroma/web/twitter_api/password_controller_test.exs
diff --git a/test/web/twitter_api/remote_follow_controller_test.exs b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/pleroma/web/twitter_api/twitter_api_test.exs
diff --git a/test/web/twitter_api/util_controller_test.exs b/test/pleroma/web/twitter_api/util_controller_test.exs
diff --git a/test/web/uploader_controller_test.exs b/test/pleroma/web/uploader_controller_test.exs
diff --git a/test/web/views/error_view_test.exs b/test/pleroma/web/views/error_view_test.exs
diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/pleroma/web/web_finger/web_finger_controller_test.exs
diff --git a/test/web/web_finger/web_finger_test.exs b/test/pleroma/web/web_finger_test.exs
diff --git a/test/workers/cron/digest_emails_worker_test.exs b/test/pleroma/workers/cron/digest_emails_worker_test.exs
diff --git a/test/workers/cron/new_users_digest_worker_test.exs b/test/pleroma/workers/cron/new_users_digest_worker_test.exs
diff --git a/test/workers/scheduled_activity_worker_test.exs b/test/pleroma/workers/scheduled_activity_worker_test.exs
diff --git a/test/xml_builder_test.exs b/test/pleroma/xml_builder_test.exs
diff --git a/test/plugs/admin_secret_authentication_plug_test.exs b/test/plugs/admin_secret_authentication_plug_test.exs
@@ -1,75 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
- use Pleroma.Web.ConnCase
-
- import Mock
- import Pleroma.Factory
-
- alias Pleroma.Plugs.AdminSecretAuthenticationPlug
- alias Pleroma.Plugs.OAuthScopesPlug
- alias Pleroma.Plugs.PlugHelper
- alias Pleroma.Plugs.RateLimiter
-
- test "does nothing if a user is assigned", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
-
- ret_conn =
- conn
- |> AdminSecretAuthenticationPlug.call(%{})
-
- assert conn == ret_conn
- end
-
- describe "when secret set it assigns an admin user" do
- setup do: clear_config([:admin_token])
-
- setup_with_mocks([{RateLimiter, [:passthrough], []}]) do
- :ok
- end
-
- test "with `admin_token` query parameter", %{conn: conn} do
- Pleroma.Config.put(:admin_token, "password123")
-
- conn =
- %{conn | params: %{"admin_token" => "wrong_password"}}
- |> AdminSecretAuthenticationPlug.call(%{})
-
- refute conn.assigns[:user]
- assert called(RateLimiter.call(conn, name: :authentication))
-
- conn =
- %{conn | params: %{"admin_token" => "password123"}}
- |> AdminSecretAuthenticationPlug.call(%{})
-
- assert conn.assigns[:user].is_admin
- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
- end
-
- test "with `x-admin-token` HTTP header", %{conn: conn} do
- Pleroma.Config.put(:admin_token, "☕️")
-
- conn =
- conn
- |> put_req_header("x-admin-token", "🥛")
- |> AdminSecretAuthenticationPlug.call(%{})
-
- refute conn.assigns[:user]
- assert called(RateLimiter.call(conn, name: :authentication))
-
- conn =
- conn
- |> put_req_header("x-admin-token", "☕️")
- |> AdminSecretAuthenticationPlug.call(%{})
-
- assert conn.assigns[:user].is_admin
- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
- end
- end
-end
diff --git a/test/plugs/authentication_plug_test.exs b/test/plugs/authentication_plug_test.exs
@@ -1,125 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.AuthenticationPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.AuthenticationPlug
- alias Pleroma.Plugs.OAuthScopesPlug
- alias Pleroma.Plugs.PlugHelper
- alias Pleroma.User
-
- import ExUnit.CaptureLog
- import Pleroma.Factory
-
- setup %{conn: conn} do
- user = %User{
- id: 1,
- name: "dude",
- password_hash: Pbkdf2.hash_pwd_salt("guy")
- }
-
- conn =
- conn
- |> assign(:auth_user, user)
-
- %{user: user, conn: conn}
- end
-
- test "it does nothing if a user is assigned", %{conn: conn} do
- conn =
- conn
- |> assign(:user, %User{})
-
- ret_conn =
- conn
- |> AuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-
- test "with a correct password in the credentials, " <>
- "it assigns the auth_user and marks OAuthScopesPlug as skipped",
- %{conn: conn} do
- conn =
- conn
- |> assign(:auth_credentials, %{password: "guy"})
- |> AuthenticationPlug.call(%{})
-
- assert conn.assigns.user == conn.assigns.auth_user
- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
- end
-
- test "with a bcrypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
- user = insert(:user, password_hash: Bcrypt.hash_pwd_salt("123"))
- assert "$2" <> _ = user.password_hash
-
- conn =
- conn
- |> assign(:auth_user, user)
- |> assign(:auth_credentials, %{password: "123"})
- |> AuthenticationPlug.call(%{})
-
- assert conn.assigns.user.id == conn.assigns.auth_user.id
- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
-
- user = User.get_by_id(user.id)
- assert "$pbkdf2" <> _ = user.password_hash
- end
-
- @tag :skip_on_mac
- test "with a crypt hash, it updates to a pkbdf2 hash", %{conn: conn} do
- user =
- insert(:user,
- password_hash:
- "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
- )
-
- conn =
- conn
- |> assign(:auth_user, user)
- |> assign(:auth_credentials, %{password: "password"})
- |> AuthenticationPlug.call(%{})
-
- assert conn.assigns.user.id == conn.assigns.auth_user.id
- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
-
- user = User.get_by_id(user.id)
- assert "$pbkdf2" <> _ = user.password_hash
- end
-
- describe "checkpw/2" do
- test "check pbkdf2 hash" do
- hash =
- "$pbkdf2-sha512$160000$loXqbp8GYls43F0i6lEfIw$AY.Ep.2pGe57j2hAPY635sI/6w7l9Q9u9Bp02PkPmF3OrClDtJAI8bCiivPr53OKMF7ph6iHhN68Rom5nEfC2A"
-
- assert AuthenticationPlug.checkpw("test-password", hash)
- refute AuthenticationPlug.checkpw("test-password1", hash)
- end
-
- @tag :skip_on_mac
- test "check sha512-crypt hash" do
- hash =
- "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
-
- assert AuthenticationPlug.checkpw("password", hash)
- end
-
- test "check bcrypt hash" do
- hash = "$2a$10$uyhC/R/zoE1ndwwCtMusK.TLVzkQ/Ugsbqp3uXI.CTTz0gBw.24jS"
-
- assert AuthenticationPlug.checkpw("password", hash)
- refute AuthenticationPlug.checkpw("password1", hash)
- end
-
- test "it returns false when hash invalid" do
- hash =
- "psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
-
- assert capture_log(fn ->
- refute Pleroma.Plugs.AuthenticationPlug.checkpw("password", hash)
- end) =~ "[error] Password hash not recognized"
- end
- end
-end
diff --git a/test/plugs/basic_auth_decoder_plug_test.exs b/test/plugs/basic_auth_decoder_plug_test.exs
@@ -1,35 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.BasicAuthDecoderPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.BasicAuthDecoderPlug
-
- defp basic_auth_enc(username, password) do
- "Basic " <> Base.encode64("#{username}:#{password}")
- end
-
- test "it puts the decoded credentials into the assigns", %{conn: conn} do
- header = basic_auth_enc("moonman", "iloverobek")
-
- conn =
- conn
- |> put_req_header("authorization", header)
- |> BasicAuthDecoderPlug.call(%{})
-
- assert conn.assigns[:auth_credentials] == %{
- username: "moonman",
- password: "iloverobek"
- }
- end
-
- test "without a authorization header it doesn't do anything", %{conn: conn} do
- ret_conn =
- conn
- |> BasicAuthDecoderPlug.call(%{})
-
- assert conn == ret_conn
- end
-end
diff --git a/test/plugs/cache_control_test.exs b/test/plugs/cache_control_test.exs
@@ -1,20 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.CacheControlTest do
- use Pleroma.Web.ConnCase
- alias Plug.Conn
-
- test "Verify Cache-Control header on static assets", %{conn: conn} do
- conn = get(conn, "/index.html")
-
- assert Conn.get_resp_header(conn, "cache-control") == ["public, no-cache"]
- end
-
- test "Verify Cache-Control header on the API", %{conn: conn} do
- conn = get(conn, "/api/v1/instance")
-
- assert Conn.get_resp_header(conn, "cache-control") == ["max-age=0, private, must-revalidate"]
- end
-end
diff --git a/test/plugs/cache_test.exs b/test/plugs/cache_test.exs
@@ -1,186 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.CacheTest do
- use ExUnit.Case, async: true
- use Plug.Test
-
- alias Pleroma.Plugs.Cache
-
- @miss_resp {200,
- [
- {"cache-control", "max-age=0, private, must-revalidate"},
- {"content-type", "cofe/hot; charset=utf-8"},
- {"x-cache", "MISS from Pleroma"}
- ], "cofe"}
-
- @hit_resp {200,
- [
- {"cache-control", "max-age=0, private, must-revalidate"},
- {"content-type", "cofe/hot; charset=utf-8"},
- {"x-cache", "HIT from Pleroma"}
- ], "cofe"}
-
- @ttl 5
-
- setup do
- Cachex.clear(:web_resp_cache)
- :ok
- end
-
- test "caches a response" do
- assert @miss_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
-
- assert_raise(Plug.Conn.AlreadySentError, fn ->
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
- end)
-
- assert @hit_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> sent_resp()
- end
-
- test "ttl is set" do
- assert @miss_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: @ttl})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
-
- assert @hit_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: @ttl})
- |> sent_resp()
-
- :timer.sleep(@ttl + 1)
-
- assert @miss_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: @ttl})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
- end
-
- test "set ttl via conn.assigns" do
- assert @miss_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> assign(:cache_ttl, @ttl)
- |> send_resp(:ok, "cofe")
- |> sent_resp()
-
- assert @hit_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> sent_resp()
-
- :timer.sleep(@ttl + 1)
-
- assert @miss_resp ==
- conn(:get, "/")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
- end
-
- test "ignore query string when `query_params` is false" do
- assert @miss_resp ==
- conn(:get, "/?cofe")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
-
- assert @hit_resp ==
- conn(:get, "/?cofefe")
- |> Cache.call(%{query_params: false, ttl: nil})
- |> sent_resp()
- end
-
- test "take query string into account when `query_params` is true" do
- assert @miss_resp ==
- conn(:get, "/?cofe")
- |> Cache.call(%{query_params: true, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
-
- assert @miss_resp ==
- conn(:get, "/?cofefe")
- |> Cache.call(%{query_params: true, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
- end
-
- test "take specific query params into account when `query_params` is list" do
- assert @miss_resp ==
- conn(:get, "/?a=1&b=2&c=3&foo=bar")
- |> fetch_query_params()
- |> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
-
- assert @hit_resp ==
- conn(:get, "/?bar=foo&c=3&b=2&a=1")
- |> fetch_query_params()
- |> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
- |> sent_resp()
-
- assert @miss_resp ==
- conn(:get, "/?bar=foo&c=3&b=2&a=2")
- |> fetch_query_params()
- |> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
- end
-
- test "ignore not GET requests" do
- expected =
- {200,
- [
- {"cache-control", "max-age=0, private, must-revalidate"},
- {"content-type", "cofe/hot; charset=utf-8"}
- ], "cofe"}
-
- assert expected ==
- conn(:post, "/")
- |> Cache.call(%{query_params: true, ttl: nil})
- |> put_resp_content_type("cofe/hot")
- |> send_resp(:ok, "cofe")
- |> sent_resp()
- end
-
- test "ignore non-successful responses" do
- expected =
- {418,
- [
- {"cache-control", "max-age=0, private, must-revalidate"},
- {"content-type", "tea/iced; charset=utf-8"}
- ], "🥤"}
-
- assert expected ==
- conn(:get, "/cofe")
- |> Cache.call(%{query_params: true, ttl: nil})
- |> put_resp_content_type("tea/iced")
- |> send_resp(:im_a_teapot, "🥤")
- |> sent_resp()
- end
-end
diff --git a/test/plugs/ensure_authenticated_plug_test.exs b/test/plugs/ensure_authenticated_plug_test.exs
@@ -1,96 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.EnsureAuthenticatedPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.EnsureAuthenticatedPlug
- alias Pleroma.User
-
- describe "without :if_func / :unless_func options" do
- test "it halts if user is NOT assigned", %{conn: conn} do
- conn = EnsureAuthenticatedPlug.call(conn, %{})
-
- assert conn.status == 403
- assert conn.halted == true
- end
-
- test "it continues if a user is assigned", %{conn: conn} do
- conn = assign(conn, :user, %User{})
- ret_conn = EnsureAuthenticatedPlug.call(conn, %{})
-
- refute ret_conn.halted
- end
- end
-
- test "it halts if user is assigned and MFA enabled", %{conn: conn} do
- conn =
- conn
- |> assign(:user, %User{multi_factor_authentication_settings: %{enabled: true}})
- |> assign(:auth_credentials, %{password: "xd-42"})
- |> EnsureAuthenticatedPlug.call(%{})
-
- assert conn.status == 403
- assert conn.halted == true
-
- assert conn.resp_body ==
- "{\"error\":\"Two-factor authentication enabled, you must use a access token.\"}"
- end
-
- test "it continues if user is assigned and MFA disabled", %{conn: conn} do
- conn =
- conn
- |> assign(:user, %User{multi_factor_authentication_settings: %{enabled: false}})
- |> assign(:auth_credentials, %{password: "xd-42"})
- |> EnsureAuthenticatedPlug.call(%{})
-
- refute conn.status == 403
- refute conn.halted
- end
-
- describe "with :if_func / :unless_func options" do
- setup do
- %{
- true_fn: fn _conn -> true end,
- false_fn: fn _conn -> false end
- }
- end
-
- test "it continues if a user is assigned", %{conn: conn, true_fn: true_fn, false_fn: false_fn} do
- conn = assign(conn, :user, %User{})
- refute EnsureAuthenticatedPlug.call(conn, if_func: true_fn).halted
- refute EnsureAuthenticatedPlug.call(conn, if_func: false_fn).halted
- refute EnsureAuthenticatedPlug.call(conn, unless_func: true_fn).halted
- refute EnsureAuthenticatedPlug.call(conn, unless_func: false_fn).halted
- end
-
- test "it continues if a user is NOT assigned but :if_func evaluates to `false`",
- %{conn: conn, false_fn: false_fn} do
- ret_conn = EnsureAuthenticatedPlug.call(conn, if_func: false_fn)
- refute ret_conn.halted
- end
-
- test "it continues if a user is NOT assigned but :unless_func evaluates to `true`",
- %{conn: conn, true_fn: true_fn} do
- ret_conn = EnsureAuthenticatedPlug.call(conn, unless_func: true_fn)
- refute ret_conn.halted
- end
-
- test "it halts if a user is NOT assigned and :if_func evaluates to `true`",
- %{conn: conn, true_fn: true_fn} do
- conn = EnsureAuthenticatedPlug.call(conn, if_func: true_fn)
-
- assert conn.status == 403
- assert conn.halted == true
- end
-
- test "it halts if a user is NOT assigned and :unless_func evaluates to `false`",
- %{conn: conn, false_fn: false_fn} do
- conn = EnsureAuthenticatedPlug.call(conn, unless_func: false_fn)
-
- assert conn.status == 403
- assert conn.halted == true
- end
- end
-end
diff --git a/test/plugs/ensure_public_or_authenticated_plug_test.exs b/test/plugs/ensure_public_or_authenticated_plug_test.exs
@@ -1,48 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Config
- alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
- alias Pleroma.User
-
- setup do: clear_config([:instance, :public])
-
- test "it halts if not public and no user is assigned", %{conn: conn} do
- Config.put([:instance, :public], false)
-
- conn =
- conn
- |> EnsurePublicOrAuthenticatedPlug.call(%{})
-
- assert conn.status == 403
- assert conn.halted == true
- end
-
- test "it continues if public", %{conn: conn} do
- Config.put([:instance, :public], true)
-
- ret_conn =
- conn
- |> EnsurePublicOrAuthenticatedPlug.call(%{})
-
- refute ret_conn.halted
- end
-
- test "it continues if a user is assigned, even if not public", %{conn: conn} do
- Config.put([:instance, :public], false)
-
- conn =
- conn
- |> assign(:user, %User{})
-
- ret_conn =
- conn
- |> EnsurePublicOrAuthenticatedPlug.call(%{})
-
- refute ret_conn.halted
- end
-end
diff --git a/test/plugs/ensure_user_key_plug_test.exs b/test/plugs/ensure_user_key_plug_test.exs
@@ -1,29 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.EnsureUserKeyPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.EnsureUserKeyPlug
-
- test "if the conn has a user key set, it does nothing", %{conn: conn} do
- conn =
- conn
- |> assign(:user, 1)
-
- ret_conn =
- conn
- |> EnsureUserKeyPlug.call(%{})
-
- assert conn == ret_conn
- end
-
- test "if the conn has no key set, it sets it to nil", %{conn: conn} do
- conn =
- conn
- |> EnsureUserKeyPlug.call(%{})
-
- assert Map.has_key?(conn.assigns, :user)
- end
-end
diff --git a/test/plugs/idempotency_plug_test.exs b/test/plugs/idempotency_plug_test.exs
@@ -1,110 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.IdempotencyPlugTest do
- use ExUnit.Case, async: true
- use Plug.Test
-
- alias Pleroma.Plugs.IdempotencyPlug
- alias Plug.Conn
-
- test "returns result from cache" do
- key = "test1"
- orig_request_id = "test1"
- second_request_id = "test2"
- body = "testing"
- status = 200
-
- :post
- |> conn("/cofe")
- |> put_req_header("idempotency-key", key)
- |> Conn.put_resp_header("x-request-id", orig_request_id)
- |> Conn.put_resp_content_type("application/json")
- |> IdempotencyPlug.call([])
- |> Conn.send_resp(status, body)
-
- conn =
- :post
- |> conn("/cofe")
- |> put_req_header("idempotency-key", key)
- |> Conn.put_resp_header("x-request-id", second_request_id)
- |> Conn.put_resp_content_type("application/json")
- |> IdempotencyPlug.call([])
-
- assert_raise Conn.AlreadySentError, fn ->
- Conn.send_resp(conn, :im_a_teapot, "no cofe")
- end
-
- assert conn.resp_body == body
- assert conn.status == status
-
- assert [^second_request_id] = Conn.get_resp_header(conn, "x-request-id")
- assert [^orig_request_id] = Conn.get_resp_header(conn, "x-original-request-id")
- assert [^key] = Conn.get_resp_header(conn, "idempotency-key")
- assert ["true"] = Conn.get_resp_header(conn, "idempotent-replayed")
- assert ["application/json; charset=utf-8"] = Conn.get_resp_header(conn, "content-type")
- end
-
- test "pass conn downstream if the cache not found" do
- key = "test2"
- orig_request_id = "test3"
- body = "testing"
- status = 200
-
- conn =
- :post
- |> conn("/cofe")
- |> put_req_header("idempotency-key", key)
- |> Conn.put_resp_header("x-request-id", orig_request_id)
- |> Conn.put_resp_content_type("application/json")
- |> IdempotencyPlug.call([])
- |> Conn.send_resp(status, body)
-
- assert conn.resp_body == body
- assert conn.status == status
-
- assert [] = Conn.get_resp_header(conn, "idempotent-replayed")
- assert [^key] = Conn.get_resp_header(conn, "idempotency-key")
- end
-
- test "passes conn downstream if idempotency is not present in headers" do
- orig_request_id = "test4"
- body = "testing"
- status = 200
-
- conn =
- :post
- |> conn("/cofe")
- |> Conn.put_resp_header("x-request-id", orig_request_id)
- |> Conn.put_resp_content_type("application/json")
- |> IdempotencyPlug.call([])
- |> Conn.send_resp(status, body)
-
- assert [] = Conn.get_resp_header(conn, "idempotency-key")
- end
-
- test "doesn't work with GET/DELETE" do
- key = "test3"
- body = "testing"
- status = 200
-
- conn =
- :get
- |> conn("/cofe")
- |> put_req_header("idempotency-key", key)
- |> IdempotencyPlug.call([])
- |> Conn.send_resp(status, body)
-
- assert [] = Conn.get_resp_header(conn, "idempotency-key")
-
- conn =
- :delete
- |> conn("/cofe")
- |> put_req_header("idempotency-key", key)
- |> IdempotencyPlug.call([])
- |> Conn.send_resp(status, body)
-
- assert [] = Conn.get_resp_header(conn, "idempotency-key")
- end
-end
diff --git a/test/plugs/instance_static_test.exs b/test/plugs/instance_static_test.exs
@@ -1,65 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.InstanceStaticPlugTest do
- use Pleroma.Web.ConnCase
-
- @dir "test/tmp/instance_static"
-
- setup do
- File.mkdir_p!(@dir)
- on_exit(fn -> File.rm_rf(@dir) end)
- end
-
- setup do: clear_config([:instance, :static_dir], @dir)
-
- test "overrides index" do
- bundled_index = get(build_conn(), "/")
- refute html_response(bundled_index, 200) == "hello world"
-
- File.write!(@dir <> "/index.html", "hello world")
-
- index = get(build_conn(), "/")
- assert html_response(index, 200) == "hello world"
- end
-
- test "also overrides frontend files", %{conn: conn} do
- name = "pelmora"
- ref = "uguu"
-
- clear_config([:frontends, :primary], %{"name" => name, "ref" => ref})
-
- bundled_index = get(conn, "/")
- refute html_response(bundled_index, 200) == "from frontend plug"
-
- path = "#{@dir}/frontends/#{name}/#{ref}"
- File.mkdir_p!(path)
- File.write!("#{path}/index.html", "from frontend plug")
-
- index = get(conn, "/")
- assert html_response(index, 200) == "from frontend plug"
-
- File.write!(@dir <> "/index.html", "from instance static")
-
- index = get(conn, "/")
- assert html_response(index, 200) == "from instance static"
- end
-
- test "overrides any file in static/static" do
- bundled_index = get(build_conn(), "/static/terms-of-service.html")
-
- assert html_response(bundled_index, 200) ==
- File.read!("priv/static/static/terms-of-service.html")
-
- File.mkdir!(@dir <> "/static")
- File.write!(@dir <> "/static/terms-of-service.html", "plz be kind")
-
- index = get(build_conn(), "/static/terms-of-service.html")
- assert html_response(index, 200) == "plz be kind"
-
- File.write!(@dir <> "/static/kaniini.html", "<h1>rabbit hugs as a service</h1>")
- index = get(build_conn(), "/static/kaniini.html")
- assert html_response(index, 200) == "<h1>rabbit hugs as a service</h1>"
- end
-end
diff --git a/test/plugs/legacy_authentication_plug_test.exs b/test/plugs/legacy_authentication_plug_test.exs
@@ -1,82 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- alias Pleroma.Plugs.LegacyAuthenticationPlug
- alias Pleroma.Plugs.OAuthScopesPlug
- alias Pleroma.Plugs.PlugHelper
- alias Pleroma.User
-
- setup do
- user =
- insert(:user,
- password: "password",
- password_hash:
- "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
- )
-
- %{user: user}
- end
-
- test "it does nothing if a user is assigned", %{conn: conn, user: user} do
- conn =
- conn
- |> assign(:auth_credentials, %{username: "dude", password: "password"})
- |> assign(:auth_user, user)
- |> assign(:user, %User{})
-
- ret_conn =
- conn
- |> LegacyAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-
- @tag :skip_on_mac
- test "if `auth_user` is present and password is correct, " <>
- "it authenticates the user, resets the password, marks OAuthScopesPlug as skipped",
- %{
- conn: conn,
- user: user
- } do
- conn =
- conn
- |> assign(:auth_credentials, %{username: "dude", password: "password"})
- |> assign(:auth_user, user)
-
- conn = LegacyAuthenticationPlug.call(conn, %{})
-
- assert conn.assigns.user.id == user.id
- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
- end
-
- @tag :skip_on_mac
- test "it does nothing if the password is wrong", %{
- conn: conn,
- user: user
- } do
- conn =
- conn
- |> assign(:auth_credentials, %{username: "dude", password: "wrong_password"})
- |> assign(:auth_user, user)
-
- ret_conn =
- conn
- |> LegacyAuthenticationPlug.call(%{})
-
- assert conn == ret_conn
- end
-
- test "with no credentials or user it does nothing", %{conn: conn} do
- ret_conn =
- conn
- |> LegacyAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-end
diff --git a/test/plugs/oauth_plug_test.exs b/test/plugs/oauth_plug_test.exs
@@ -1,80 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.OAuthPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.OAuthPlug
- import Pleroma.Factory
-
- @session_opts [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
-
- setup %{conn: conn} do
- user = insert(:user)
- {:ok, %{token: token}} = Pleroma.Web.OAuth.Token.create(insert(:oauth_app), user)
- %{user: user, token: token, conn: conn}
- end
-
- test "with valid token(uppercase), it assigns the user", %{conn: conn} = opts do
- conn =
- conn
- |> put_req_header("authorization", "BEARER #{opts[:token]}")
- |> OAuthPlug.call(%{})
-
- assert conn.assigns[:user] == opts[:user]
- end
-
- test "with valid token(downcase), it assigns the user", %{conn: conn} = opts do
- conn =
- conn
- |> put_req_header("authorization", "bearer #{opts[:token]}")
- |> OAuthPlug.call(%{})
-
- assert conn.assigns[:user] == opts[:user]
- end
-
- test "with valid token(downcase) in url parameters, it assigns the user", opts do
- conn =
- :get
- |> build_conn("/?access_token=#{opts[:token]}")
- |> put_req_header("content-type", "application/json")
- |> fetch_query_params()
- |> OAuthPlug.call(%{})
-
- assert conn.assigns[:user] == opts[:user]
- end
-
- test "with valid token(downcase) in body parameters, it assigns the user", opts do
- conn =
- :post
- |> build_conn("/api/v1/statuses", access_token: opts[:token], status: "test")
- |> OAuthPlug.call(%{})
-
- assert conn.assigns[:user] == opts[:user]
- end
-
- test "with invalid token, it not assigns the user", %{conn: conn} do
- conn =
- conn
- |> put_req_header("authorization", "bearer TTTTT")
- |> OAuthPlug.call(%{})
-
- refute conn.assigns[:user]
- end
-
- test "when token is missed but token in session, it assigns the user", %{conn: conn} = opts do
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(@session_opts))
- |> fetch_session()
- |> put_session(:oauth_token, opts[:token])
- |> OAuthPlug.call(%{})
-
- assert conn.assigns[:user] == opts[:user]
- end
-end
diff --git a/test/plugs/oauth_scopes_plug_test.exs b/test/plugs/oauth_scopes_plug_test.exs
@@ -1,210 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.OAuthScopesPlugTest do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Plugs.OAuthScopesPlug
- alias Pleroma.Repo
-
- import Mock
- import Pleroma.Factory
-
- test "is not performed if marked as skipped", %{conn: conn} do
- with_mock OAuthScopesPlug, [:passthrough], perform: &passthrough([&1, &2]) do
- conn =
- conn
- |> OAuthScopesPlug.skip_plug()
- |> OAuthScopesPlug.call(%{scopes: ["random_scope"]})
-
- refute called(OAuthScopesPlug.perform(:_, :_))
- refute conn.halted
- end
- end
-
- test "if `token.scopes` fulfills specified 'any of' conditions, " <>
- "proceeds with no op",
- %{conn: conn} do
- token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
-
- conn =
- conn
- |> assign(:user, token.user)
- |> assign(:token, token)
- |> OAuthScopesPlug.call(%{scopes: ["read"]})
-
- refute conn.halted
- assert conn.assigns[:user]
- end
-
- test "if `token.scopes` fulfills specified 'all of' conditions, " <>
- "proceeds with no op",
- %{conn: conn} do
- token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)
-
- conn =
- conn
- |> assign(:user, token.user)
- |> assign(:token, token)
- |> OAuthScopesPlug.call(%{scopes: ["scope2", "scope3"], op: :&})
-
- refute conn.halted
- assert conn.assigns[:user]
- end
-
- describe "with `fallback: :proceed_unauthenticated` option, " do
- test "if `token.scopes` doesn't fulfill specified conditions, " <>
- "clears :user and :token assigns",
- %{conn: conn} do
- user = insert(:user)
- token1 = insert(:oauth_token, scopes: ["read", "write"], user: user)
-
- for token <- [token1, nil], op <- [:|, :&] do
- ret_conn =
- conn
- |> assign(:user, user)
- |> assign(:token, token)
- |> OAuthScopesPlug.call(%{
- scopes: ["follow"],
- op: op,
- fallback: :proceed_unauthenticated
- })
-
- refute ret_conn.halted
- refute ret_conn.assigns[:user]
- refute ret_conn.assigns[:token]
- end
- end
- end
-
- describe "without :fallback option, " do
- test "if `token.scopes` does not fulfill specified 'any of' conditions, " <>
- "returns 403 and halts",
- %{conn: conn} do
- for token <- [insert(:oauth_token, scopes: ["read", "write"]), nil] do
- any_of_scopes = ["follow", "push"]
-
- ret_conn =
- conn
- |> assign(:token, token)
- |> OAuthScopesPlug.call(%{scopes: any_of_scopes})
-
- assert ret_conn.halted
- assert 403 == ret_conn.status
-
- expected_error = "Insufficient permissions: #{Enum.join(any_of_scopes, " | ")}."
- assert Jason.encode!(%{error: expected_error}) == ret_conn.resp_body
- end
- end
-
- test "if `token.scopes` does not fulfill specified 'all of' conditions, " <>
- "returns 403 and halts",
- %{conn: conn} do
- for token <- [insert(:oauth_token, scopes: ["read", "write"]), nil] do
- token_scopes = (token && token.scopes) || []
- all_of_scopes = ["write", "follow"]
-
- conn =
- conn
- |> assign(:token, token)
- |> OAuthScopesPlug.call(%{scopes: all_of_scopes, op: :&})
-
- assert conn.halted
- assert 403 == conn.status
-
- expected_error =
- "Insufficient permissions: #{Enum.join(all_of_scopes -- token_scopes, " & ")}."
-
- assert Jason.encode!(%{error: expected_error}) == conn.resp_body
- end
- end
- end
-
- describe "with hierarchical scopes, " do
- test "if `token.scopes` fulfills specified 'any of' conditions, " <>
- "proceeds with no op",
- %{conn: conn} do
- token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
-
- conn =
- conn
- |> assign(:user, token.user)
- |> assign(:token, token)
- |> OAuthScopesPlug.call(%{scopes: ["read:something"]})
-
- refute conn.halted
- assert conn.assigns[:user]
- end
-
- test "if `token.scopes` fulfills specified 'all of' conditions, " <>
- "proceeds with no op",
- %{conn: conn} do
- token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)
-
- conn =
- conn
- |> assign(:user, token.user)
- |> assign(:token, token)
- |> OAuthScopesPlug.call(%{scopes: ["scope1:subscope", "scope2:subscope"], op: :&})
-
- refute conn.halted
- assert conn.assigns[:user]
- end
- end
-
- describe "filter_descendants/2" do
- test "filters scopes which directly match or are ancestors of supported scopes" do
- f = fn scopes, supported_scopes ->
- OAuthScopesPlug.filter_descendants(scopes, supported_scopes)
- end
-
- assert f.(["read", "follow"], ["write", "read"]) == ["read"]
-
- assert f.(["read", "write:something", "follow"], ["write", "read"]) ==
- ["read", "write:something"]
-
- assert f.(["admin:read"], ["write", "read"]) == []
-
- assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"]
- end
- end
-
- describe "transform_scopes/2" do
- setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage])
-
- setup do
- {:ok, %{f: &OAuthScopesPlug.transform_scopes/2}}
- end
-
- test "with :admin option, prefixes all requested scopes with `admin:` " <>
- "and [optionally] keeps only prefixed scopes, " <>
- "depending on `[:auth, :enforce_oauth_admin_scope_usage]` setting",
- %{f: f} do
- Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
-
- assert f.(["read"], %{admin: true}) == ["admin:read", "read"]
-
- assert f.(["read", "write"], %{admin: true}) == [
- "admin:read",
- "read",
- "admin:write",
- "write"
- ]
-
- Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
-
- assert f.(["read:accounts"], %{admin: true}) == ["admin:read:accounts"]
-
- assert f.(["read", "write:reports"], %{admin: true}) == [
- "admin:read",
- "admin:write:reports"
- ]
- end
-
- test "with no supported options, returns unmodified scopes", %{f: f} do
- assert f.(["read"], %{}) == ["read"]
- assert f.(["read", "write"], %{}) == ["read", "write"]
- end
- end
-end
diff --git a/test/plugs/rate_limiter_test.exs b/test/plugs/rate_limiter_test.exs
@@ -1,263 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.RateLimiterTest do
- use Pleroma.Web.ConnCase
-
- alias Phoenix.ConnTest
- alias Pleroma.Config
- alias Pleroma.Plugs.RateLimiter
- alias Plug.Conn
-
- import Pleroma.Factory
- import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
-
- # Note: each example must work with separate buckets in order to prevent concurrency issues
- setup do: clear_config([Pleroma.Web.Endpoint, :http, :ip])
- setup do: clear_config(:rate_limit)
-
- describe "config" do
- @limiter_name :test_init
- setup do: clear_config([Pleroma.Plugs.RemoteIp, :enabled])
-
- test "config is required for plug to work" do
- Config.put([:rate_limit, @limiter_name], {1, 1})
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
-
- assert %{limits: {1, 1}, name: :test_init, opts: [name: :test_init]} ==
- [name: @limiter_name]
- |> RateLimiter.init()
- |> RateLimiter.action_settings()
-
- assert nil ==
- [name: :nonexisting_limiter]
- |> RateLimiter.init()
- |> RateLimiter.action_settings()
- end
- end
-
- test "it is disabled if it remote ip plug is enabled but no remote ip is found" do
- assert RateLimiter.disabled?(Conn.assign(build_conn(), :remote_ip_found, false))
- end
-
- test "it is enabled if remote ip found" do
- refute RateLimiter.disabled?(Conn.assign(build_conn(), :remote_ip_found, true))
- end
-
- test "it is enabled if remote_ip_found flag doesn't exist" do
- refute RateLimiter.disabled?(build_conn())
- end
-
- test "it restricts based on config values" do
- limiter_name = :test_plug_opts
- scale = 80
- limit = 5
-
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
- Config.put([:rate_limit, limiter_name], {scale, limit})
-
- plug_opts = RateLimiter.init(name: limiter_name)
- conn = build_conn(:get, "/")
-
- for i <- 1..5 do
- conn = RateLimiter.call(conn, plug_opts)
- assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
- Process.sleep(10)
- end
-
- conn = RateLimiter.call(conn, plug_opts)
- assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
- assert conn.halted
-
- Process.sleep(50)
-
- conn = build_conn(:get, "/")
-
- conn = RateLimiter.call(conn, plug_opts)
- assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
-
- refute conn.status == Conn.Status.code(:too_many_requests)
- refute conn.resp_body
- refute conn.halted
- end
-
- describe "options" do
- test "`bucket_name` option overrides default bucket name" do
- limiter_name = :test_bucket_name
-
- Config.put([:rate_limit, limiter_name], {1000, 5})
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
-
- base_bucket_name = "#{limiter_name}:group1"
- plug_opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name)
-
- conn = build_conn(:get, "/")
-
- RateLimiter.call(conn, plug_opts)
- assert {1, 4} = RateLimiter.inspect_bucket(conn, base_bucket_name, plug_opts)
- assert {:error, :not_found} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
- end
-
- test "`params` option allows different queries to be tracked independently" do
- limiter_name = :test_params
- Config.put([:rate_limit, limiter_name], {1000, 5})
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
-
- plug_opts = RateLimiter.init(name: limiter_name, params: ["id"])
-
- conn = build_conn(:get, "/?id=1")
- conn = Conn.fetch_query_params(conn)
- conn_2 = build_conn(:get, "/?id=2")
-
- RateLimiter.call(conn, plug_opts)
- assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
- assert {0, 5} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
- end
-
- test "it supports combination of options modifying bucket name" do
- limiter_name = :test_options_combo
- Config.put([:rate_limit, limiter_name], {1000, 5})
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
-
- base_bucket_name = "#{limiter_name}:group1"
-
- plug_opts =
- RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name, params: ["id"])
-
- id = "100"
-
- conn = build_conn(:get, "/?id=#{id}")
- conn = Conn.fetch_query_params(conn)
- conn_2 = build_conn(:get, "/?id=#{101}")
-
- RateLimiter.call(conn, plug_opts)
- assert {1, 4} = RateLimiter.inspect_bucket(conn, base_bucket_name, plug_opts)
- assert {0, 5} = RateLimiter.inspect_bucket(conn_2, base_bucket_name, plug_opts)
- end
- end
-
- describe "unauthenticated users" do
- test "are restricted based on remote IP" do
- limiter_name = :test_unauthenticated
- Config.put([:rate_limit, limiter_name], [{1000, 5}, {1, 10}])
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
-
- plug_opts = RateLimiter.init(name: limiter_name)
-
- conn = %{build_conn(:get, "/") | remote_ip: {127, 0, 0, 2}}
- conn_2 = %{build_conn(:get, "/") | remote_ip: {127, 0, 0, 3}}
-
- for i <- 1..5 do
- conn = RateLimiter.call(conn, plug_opts)
- assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
- refute conn.halted
- end
-
- conn = RateLimiter.call(conn, plug_opts)
-
- assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
- assert conn.halted
-
- conn_2 = RateLimiter.call(conn_2, plug_opts)
- assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
-
- refute conn_2.status == Conn.Status.code(:too_many_requests)
- refute conn_2.resp_body
- refute conn_2.halted
- end
- end
-
- describe "authenticated users" do
- setup do
- Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo)
-
- :ok
- end
-
- test "can have limits separate from unauthenticated connections" do
- limiter_name = :test_authenticated1
-
- scale = 50
- limit = 5
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
- Config.put([:rate_limit, limiter_name], [{1000, 1}, {scale, limit}])
-
- plug_opts = RateLimiter.init(name: limiter_name)
-
- user = insert(:user)
- conn = build_conn(:get, "/") |> assign(:user, user)
-
- for i <- 1..5 do
- conn = RateLimiter.call(conn, plug_opts)
- assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
- refute conn.halted
- end
-
- conn = RateLimiter.call(conn, plug_opts)
-
- assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
- assert conn.halted
- end
-
- test "different users are counted independently" do
- limiter_name = :test_authenticated2
- Config.put([:rate_limit, limiter_name], [{1, 10}, {1000, 5}])
- Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
-
- plug_opts = RateLimiter.init(name: limiter_name)
-
- user = insert(:user)
- conn = build_conn(:get, "/") |> assign(:user, user)
-
- user_2 = insert(:user)
- conn_2 = build_conn(:get, "/") |> assign(:user, user_2)
-
- for i <- 1..5 do
- conn = RateLimiter.call(conn, plug_opts)
- assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
- end
-
- conn = RateLimiter.call(conn, plug_opts)
- assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
- assert conn.halted
-
- conn_2 = RateLimiter.call(conn_2, plug_opts)
- assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
- refute conn_2.status == Conn.Status.code(:too_many_requests)
- refute conn_2.resp_body
- refute conn_2.halted
- end
- end
-
- test "doesn't crash due to a race condition when multiple requests are made at the same time and the bucket is not yet initialized" do
- limiter_name = :test_race_condition
- Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
- Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
-
- opts = RateLimiter.init(name: limiter_name)
-
- conn = build_conn(:get, "/")
- conn_2 = build_conn(:get, "/")
-
- %Task{pid: pid1} =
- task1 =
- Task.async(fn ->
- receive do
- :process2_up ->
- RateLimiter.call(conn, opts)
- end
- end)
-
- task2 =
- Task.async(fn ->
- send(pid1, :process2_up)
- RateLimiter.call(conn_2, opts)
- end)
-
- Task.await(task1)
- Task.await(task2)
-
- refute {:err, :not_found} == RateLimiter.inspect_bucket(conn, limiter_name, opts)
- end
-end
diff --git a/test/plugs/remote_ip_test.exs b/test/plugs/remote_ip_test.exs
@@ -1,108 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.RemoteIpTest do
- use ExUnit.Case
- use Plug.Test
-
- alias Pleroma.Plugs.RemoteIp
-
- import Pleroma.Tests.Helpers, only: [clear_config: 2]
-
- setup do:
- clear_config(RemoteIp,
- enabled: true,
- headers: ["x-forwarded-for"],
- proxies: [],
- reserved: [
- "127.0.0.0/8",
- "::1/128",
- "fc00::/7",
- "10.0.0.0/8",
- "172.16.0.0/12",
- "192.168.0.0/16"
- ]
- )
-
- test "disabled" do
- Pleroma.Config.put(RemoteIp, enabled: false)
-
- %{remote_ip: remote_ip} = conn(:get, "/")
-
- conn =
- conn(:get, "/")
- |> put_req_header("x-forwarded-for", "1.1.1.1")
- |> RemoteIp.call(nil)
-
- assert conn.remote_ip == remote_ip
- end
-
- test "enabled" do
- conn =
- conn(:get, "/")
- |> put_req_header("x-forwarded-for", "1.1.1.1")
- |> RemoteIp.call(nil)
-
- assert conn.remote_ip == {1, 1, 1, 1}
- end
-
- test "custom headers" do
- Pleroma.Config.put(RemoteIp, enabled: true, headers: ["cf-connecting-ip"])
-
- conn =
- conn(:get, "/")
- |> put_req_header("x-forwarded-for", "1.1.1.1")
- |> RemoteIp.call(nil)
-
- refute conn.remote_ip == {1, 1, 1, 1}
-
- conn =
- conn(:get, "/")
- |> put_req_header("cf-connecting-ip", "1.1.1.1")
- |> RemoteIp.call(nil)
-
- assert conn.remote_ip == {1, 1, 1, 1}
- end
-
- test "custom proxies" do
- conn =
- conn(:get, "/")
- |> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1, 173.245.48.2")
- |> RemoteIp.call(nil)
-
- refute conn.remote_ip == {1, 1, 1, 1}
-
- Pleroma.Config.put([RemoteIp, :proxies], ["173.245.48.0/20"])
-
- conn =
- conn(:get, "/")
- |> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1, 173.245.48.2")
- |> RemoteIp.call(nil)
-
- assert conn.remote_ip == {1, 1, 1, 1}
- end
-
- test "proxies set without CIDR format" do
- Pleroma.Config.put([RemoteIp, :proxies], ["173.245.48.1"])
-
- conn =
- conn(:get, "/")
- |> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1")
- |> RemoteIp.call(nil)
-
- assert conn.remote_ip == {1, 1, 1, 1}
- end
-
- test "proxies set `nonsensical` CIDR" do
- Pleroma.Config.put([RemoteIp, :reserved], ["127.0.0.0/8"])
- Pleroma.Config.put([RemoteIp, :proxies], ["10.0.0.3/24"])
-
- conn =
- conn(:get, "/")
- |> put_req_header("x-forwarded-for", "10.0.0.3, 1.1.1.1")
- |> RemoteIp.call(nil)
-
- assert conn.remote_ip == {1, 1, 1, 1}
- end
-end
diff --git a/test/plugs/session_authentication_plug_test.exs b/test/plugs/session_authentication_plug_test.exs
@@ -1,63 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.SessionAuthenticationPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.SessionAuthenticationPlug
- alias Pleroma.User
-
- setup %{conn: conn} do
- session_opts = [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
-
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(session_opts))
- |> fetch_session
- |> assign(:auth_user, %User{id: 1})
-
- %{conn: conn}
- end
-
- test "it does nothing if a user is assigned", %{conn: conn} do
- conn =
- conn
- |> assign(:user, %User{})
-
- ret_conn =
- conn
- |> SessionAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-
- test "if the auth_user has the same id as the user_id in the session, it assigns the user", %{
- conn: conn
- } do
- conn =
- conn
- |> put_session(:user_id, conn.assigns.auth_user.id)
- |> SessionAuthenticationPlug.call(%{})
-
- assert conn.assigns.user == conn.assigns.auth_user
- end
-
- test "if the auth_user has a different id as the user_id in the session, it does nothing", %{
- conn: conn
- } do
- conn =
- conn
- |> put_session(:user_id, -1)
-
- ret_conn =
- conn
- |> SessionAuthenticationPlug.call(%{})
-
- assert ret_conn == conn
- end
-end
diff --git a/test/plugs/set_format_plug_test.exs b/test/plugs/set_format_plug_test.exs
@@ -1,38 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.SetFormatPlugTest do
- use ExUnit.Case, async: true
- use Plug.Test
-
- alias Pleroma.Plugs.SetFormatPlug
-
- test "set format from params" do
- conn =
- :get
- |> conn("/cofe?_format=json")
- |> SetFormatPlug.call([])
-
- assert %{format: "json"} == conn.assigns
- end
-
- test "set format from header" do
- conn =
- :get
- |> conn("/cofe")
- |> put_private(:phoenix_format, "xml")
- |> SetFormatPlug.call([])
-
- assert %{format: "xml"} == conn.assigns
- end
-
- test "doesn't set format" do
- conn =
- :get
- |> conn("/cofe")
- |> SetFormatPlug.call([])
-
- refute conn.assigns[:format]
- end
-end
diff --git a/test/plugs/set_locale_plug_test.exs b/test/plugs/set_locale_plug_test.exs
@@ -1,46 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.SetLocalePlugTest do
- use ExUnit.Case, async: true
- use Plug.Test
-
- alias Pleroma.Plugs.SetLocalePlug
- alias Plug.Conn
-
- test "default locale is `en`" do
- conn =
- :get
- |> conn("/cofe")
- |> SetLocalePlug.call([])
-
- assert "en" == Gettext.get_locale()
- assert %{locale: "en"} == conn.assigns
- end
-
- test "use supported locale from `accept-language`" do
- conn =
- :get
- |> conn("/cofe")
- |> Conn.put_req_header(
- "accept-language",
- "ru, fr-CH, fr;q=0.9, en;q=0.8, *;q=0.5"
- )
- |> SetLocalePlug.call([])
-
- assert "ru" == Gettext.get_locale()
- assert %{locale: "ru"} == conn.assigns
- end
-
- test "use default locale if locale from `accept-language` is not supported" do
- conn =
- :get
- |> conn("/cofe")
- |> Conn.put_req_header("accept-language", "tlh")
- |> SetLocalePlug.call([])
-
- assert "en" == Gettext.get_locale()
- assert %{locale: "en"} == conn.assigns
- end
-end
diff --git a/test/plugs/set_user_session_id_plug_test.exs b/test/plugs/set_user_session_id_plug_test.exs
@@ -1,45 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.SetUserSessionIdPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.SetUserSessionIdPlug
- alias Pleroma.User
-
- setup %{conn: conn} do
- session_opts = [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
-
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(session_opts))
- |> fetch_session
-
- %{conn: conn}
- end
-
- test "doesn't do anything if the user isn't set", %{conn: conn} do
- ret_conn =
- conn
- |> SetUserSessionIdPlug.call(%{})
-
- assert ret_conn == conn
- end
-
- test "sets the user_id in the session to the user id of the user assign", %{conn: conn} do
- Code.ensure_compiled(Pleroma.User)
-
- conn =
- conn
- |> assign(:user, %User{id: 1})
- |> SetUserSessionIdPlug.call(%{})
-
- id = get_session(conn, :user_id)
- assert id == 1
- end
-end
diff --git a/test/plugs/uploaded_media_plug_test.exs b/test/plugs/uploaded_media_plug_test.exs
@@ -1,43 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.UploadedMediaPlugTest do
- use Pleroma.Web.ConnCase
- alias Pleroma.Upload
-
- defp upload_file(context) do
- Pleroma.DataCase.ensure_local_uploader(context)
- File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image_tmp.jpg"),
- filename: "nice_tf.jpg"
- }
-
- {:ok, data} = Upload.store(file)
- [%{"href" => attachment_url} | _] = data["url"]
- [attachment_url: attachment_url]
- end
-
- setup_all :upload_file
-
- test "does not send Content-Disposition header when name param is not set", %{
- attachment_url: attachment_url
- } do
- conn = get(build_conn(), attachment_url)
- refute Enum.any?(conn.resp_headers, &(elem(&1, 0) == "content-disposition"))
- end
-
- test "sends Content-Disposition header when name param is set", %{
- attachment_url: attachment_url
- } do
- conn = get(build_conn(), attachment_url <> "?name=\"cofe\".gif")
-
- assert Enum.any?(
- conn.resp_headers,
- &(&1 == {"content-disposition", "filename=\"\\\"cofe\\\".gif\""})
- )
- end
-end
diff --git a/test/plugs/user_enabled_plug_test.exs b/test/plugs/user_enabled_plug_test.exs
@@ -1,59 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.UserEnabledPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.UserEnabledPlug
- import Pleroma.Factory
-
- setup do: clear_config([:instance, :account_activation_required])
-
- test "doesn't do anything if the user isn't set", %{conn: conn} do
- ret_conn =
- conn
- |> UserEnabledPlug.call(%{})
-
- assert ret_conn == conn
- end
-
- test "with a user that's not confirmed and a config requiring confirmation, it removes that user",
- %{conn: conn} do
- Pleroma.Config.put([:instance, :account_activation_required], true)
-
- user = insert(:user, confirmation_pending: true)
-
- conn =
- conn
- |> assign(:user, user)
- |> UserEnabledPlug.call(%{})
-
- assert conn.assigns.user == nil
- end
-
- test "with a user that is deactivated, it removes that user", %{conn: conn} do
- user = insert(:user, deactivated: true)
-
- conn =
- conn
- |> assign(:user, user)
- |> UserEnabledPlug.call(%{})
-
- assert conn.assigns.user == nil
- end
-
- test "with a user that is not deactivated, it does nothing", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
-
- ret_conn =
- conn
- |> UserEnabledPlug.call(%{})
-
- assert conn == ret_conn
- end
-end
diff --git a/test/plugs/user_fetcher_plug_test.exs b/test/plugs/user_fetcher_plug_test.exs
@@ -1,41 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.UserFetcherPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.UserFetcherPlug
- import Pleroma.Factory
-
- setup do
- user = insert(:user)
- %{user: user}
- end
-
- test "if an auth_credentials assign is present, it tries to fetch the user and assigns it", %{
- conn: conn,
- user: user
- } do
- conn =
- conn
- |> assign(:auth_credentials, %{
- username: user.nickname,
- password: nil
- })
-
- conn =
- conn
- |> UserFetcherPlug.call(%{})
-
- assert conn.assigns[:auth_user] == user
- end
-
- test "without a credential assign it doesn't do anything", %{conn: conn} do
- ret_conn =
- conn
- |> UserFetcherPlug.call(%{})
-
- assert conn == ret_conn
- end
-end
diff --git a/test/plugs/user_is_admin_plug_test.exs b/test/plugs/user_is_admin_plug_test.exs
@@ -1,37 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Plugs.UserIsAdminPlugTest do
- use Pleroma.Web.ConnCase, async: true
-
- alias Pleroma.Plugs.UserIsAdminPlug
- import Pleroma.Factory
-
- test "accepts a user that is an admin" do
- user = insert(:user, is_admin: true)
-
- conn = assign(build_conn(), :user, user)
-
- ret_conn = UserIsAdminPlug.call(conn, %{})
-
- assert conn == ret_conn
- end
-
- test "denies a user that isn't an admin" do
- user = insert(:user)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> UserIsAdminPlug.call(%{})
-
- assert conn.status == 403
- end
-
- test "denies when a user isn't set" do
- conn = UserIsAdminPlug.call(build_conn(), %{})
-
- assert conn.status == 403
- end
-end
diff --git a/test/runtime_test.exs b/test/runtime_test.exs
@@ -1,11 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.RuntimeTest do
- use ExUnit.Case, async: true
-
- test "it loads custom runtime modules" do
- assert {:module, RuntimeModule} == Code.ensure_compiled(RuntimeModule)
- end
-end
diff --git a/test/support/captcha_mock.ex b/test/support/captcha/mock.ex
diff --git a/test/web/activity_pub/object_validators/types/date_time_test.exs b/test/web/activity_pub/object_validators/types/date_time_test.exs
@@ -1,36 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTimeTest do
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime
- use Pleroma.DataCase
-
- test "it validates an xsd:Datetime" do
- valid_strings = [
- "2004-04-12T13:20:00",
- "2004-04-12T13:20:15.5",
- "2004-04-12T13:20:00-05:00",
- "2004-04-12T13:20:00Z"
- ]
-
- invalid_strings = [
- "2004-04-12T13:00",
- "2004-04-1213:20:00",
- "99-04-12T13:00",
- "2004-04-12"
- ]
-
- assert {:ok, "2004-04-01T12:00:00Z"} == DateTime.cast("2004-04-01T12:00:00Z")
-
- Enum.each(valid_strings, fn date_time ->
- result = DateTime.cast(date_time)
- assert {:ok, _} = result
- end)
-
- Enum.each(invalid_strings, fn date_time ->
- result = DateTime.cast(date_time)
- assert :error == result
- end)
- end
-end
diff --git a/test/web/activity_pub/object_validators/types/object_id_test.exs b/test/web/activity_pub/object_validators/types/object_id_test.exs
@@ -1,41 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ObjectValidators.Types.ObjectIDTest do
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID
- use Pleroma.DataCase
-
- @uris [
- "http://lain.com/users/lain",
- "http://lain.com",
- "https://lain.com/object/1"
- ]
-
- @non_uris [
- "https://",
- "rin",
- 1,
- :x,
- %{"1" => 2}
- ]
-
- test "it accepts http uris" do
- Enum.each(@uris, fn uri ->
- assert {:ok, uri} == ObjectID.cast(uri)
- end)
- end
-
- test "it accepts an object with a nested uri id" do
- Enum.each(@uris, fn uri ->
- assert {:ok, uri} == ObjectID.cast(%{"id" => uri})
- end)
- end
-
- test "it rejects non-uri strings" do
- Enum.each(@non_uris, fn non_uri ->
- assert :error == ObjectID.cast(non_uri)
- assert :error == ObjectID.cast(%{"id" => non_uri})
- end)
- end
-end
diff --git a/test/web/activity_pub/object_validators/types/recipients_test.exs b/test/web/activity_pub/object_validators/types/recipients_test.exs
@@ -1,31 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ObjectValidators.Types.RecipientsTest do
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients
- use Pleroma.DataCase
-
- test "it asserts that all elements of the list are object ids" do
- list = ["https://lain.com/users/lain", "invalid"]
-
- assert :error == Recipients.cast(list)
- end
-
- test "it works with a list" do
- list = ["https://lain.com/users/lain"]
- assert {:ok, list} == Recipients.cast(list)
- end
-
- test "it works with a list with whole objects" do
- list = ["https://lain.com/users/lain", %{"id" => "https://gensokyo.2hu/users/raymoo"}]
- resulting_list = ["https://gensokyo.2hu/users/raymoo", "https://lain.com/users/lain"]
- assert {:ok, resulting_list} == Recipients.cast(list)
- end
-
- test "it turns a single string into a list" do
- recipient = "https://lain.com/users/lain"
-
- assert {:ok, [recipient]} == Recipients.cast(recipient)
- end
-end
diff --git a/test/web/activity_pub/object_validators/types/safe_text_test.exs b/test/web/activity_pub/object_validators/types/safe_text_test.exs
@@ -1,30 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.SafeTextTest do
- use Pleroma.DataCase
-
- alias Pleroma.EctoType.ActivityPub.ObjectValidators.SafeText
-
- test "it lets normal text go through" do
- text = "hey how are you"
- assert {:ok, text} == SafeText.cast(text)
- end
-
- test "it removes html tags from text" do
- text = "hey look xss <script>alert('foo')</script>"
- assert {:ok, "hey look xss alert('foo')"} == SafeText.cast(text)
- end
-
- test "it keeps basic html tags" do
- text = "hey <a href='http://gensokyo.2hu'>look</a> xss <script>alert('foo')</script>"
-
- assert {:ok, "hey <a href=\"http://gensokyo.2hu\">look</a> xss alert('foo')"} ==
- SafeText.cast(text)
- end
-
- test "errors for non-text" do
- assert :error == SafeText.cast(1)
- end
-end
diff --git a/test/web/auth/auth_test_controller_test.exs b/test/web/auth/auth_test_controller_test.exs
@@ -1,242 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Tests.AuthTestControllerTest do
- use Pleroma.Web.ConnCase
-
- import Pleroma.Factory
-
- describe "do_oauth_check" do
- test "serves with proper OAuth token (fulfilling requested scopes)" do
- %{conn: good_token_conn, user: user} = oauth_access(["read"])
-
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/authenticated_api/do_oauth_check")
- |> json_response(200)
-
- # Unintended usage (:api) — use with :authenticated_api instead
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/api/do_oauth_check")
- |> json_response(200)
- end
-
- test "fails on no token / missing scope(s)" do
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- bad_token_conn
- |> get("/test/authenticated_api/do_oauth_check")
- |> json_response(403)
-
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/do_oauth_check")
- |> json_response(403)
- end
- end
-
- describe "fallback_oauth_check" do
- test "serves with proper OAuth token (fulfilling requested scopes)" do
- %{conn: good_token_conn, user: user} = oauth_access(["read"])
-
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/api/fallback_oauth_check")
- |> json_response(200)
-
- # Unintended usage (:authenticated_api) — use with :api instead
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/authenticated_api/fallback_oauth_check")
- |> json_response(200)
- end
-
- test "for :api on public instance, drops :user and renders on no token / missing scope(s)" do
- clear_config([:instance, :public], true)
-
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> get("/test/api/fallback_oauth_check")
- |> json_response(200)
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/fallback_oauth_check")
- |> json_response(200)
- end
-
- test "for :api on private instance, fails on no token / missing scope(s)" do
- clear_config([:instance, :public], false)
-
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- bad_token_conn
- |> get("/test/api/fallback_oauth_check")
- |> json_response(403)
-
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/fallback_oauth_check")
- |> json_response(403)
- end
- end
-
- describe "skip_oauth_check" do
- test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
- user = insert(:user)
-
- assert %{"user_id" => user.id} ==
- build_conn()
- |> assign(:user, user)
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(200)
-
- %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
-
- assert %{"user_id" => user.id} ==
- bad_token_conn
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(200)
- end
-
- test "serves via :api on public instance if :user is not set" do
- clear_config([:instance, :public], true)
-
- assert %{"user_id" => nil} ==
- build_conn()
- |> get("/test/api/skip_oauth_check")
- |> json_response(200)
-
- build_conn()
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(403)
- end
-
- test "fails on private instance if :user is not set" do
- clear_config([:instance, :public], false)
-
- build_conn()
- |> get("/test/api/skip_oauth_check")
- |> json_response(403)
-
- build_conn()
- |> get("/test/authenticated_api/skip_oauth_check")
- |> json_response(403)
- end
- end
-
- describe "fallback_oauth_skip_publicity_check" do
- test "serves with proper OAuth token (fulfilling requested scopes)" do
- %{conn: good_token_conn, user: user} = oauth_access(["read"])
-
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
-
- # Unintended usage (:authenticated_api)
- assert %{"user_id" => user.id} ==
- good_token_conn
- |> get("/test/authenticated_api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
- end
-
- test "for :api on private / public instance, drops :user and renders on token issue" do
- %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
-
- for is_public <- [true, false] do
- clear_config([:instance, :public], is_public)
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> get("/test/api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
-
- assert %{"user_id" => nil} ==
- bad_token_conn
- |> assign(:token, nil)
- |> get("/test/api/fallback_oauth_skip_publicity_check")
- |> json_response(200)
- end
- end
- end
-
- describe "skip_oauth_skip_publicity_check" do
- test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
- user = insert(:user)
-
- assert %{"user_id" => user.id} ==
- build_conn()
- |> assign(:user, user)
- |> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
- |> json_response(200)
-
- %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
-
- assert %{"user_id" => user.id} ==
- bad_token_conn
- |> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
- |> json_response(200)
- end
-
- test "for :api, serves on private and public instances regardless of whether :user is set" do
- user = insert(:user)
-
- for is_public <- [true, false] do
- clear_config([:instance, :public], is_public)
-
- assert %{"user_id" => nil} ==
- build_conn()
- |> get("/test/api/skip_oauth_skip_publicity_check")
- |> json_response(200)
-
- assert %{"user_id" => user.id} ==
- build_conn()
- |> assign(:user, user)
- |> get("/test/api/skip_oauth_skip_publicity_check")
- |> json_response(200)
- end
- end
- end
-
- describe "missing_oauth_check_definition" do
- def test_missing_oauth_check_definition_failure(endpoint, expected_error) do
- %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
-
- assert %{"error" => expected_error} ==
- conn
- |> get(endpoint)
- |> json_response(403)
- end
-
- test "fails if served via :authenticated_api" do
- test_missing_oauth_check_definition_failure(
- "/test/authenticated_api/missing_oauth_check_definition",
- "Security violation: OAuth scopes check was neither handled nor explicitly skipped."
- )
- end
-
- test "fails if served via :api and the instance is private" do
- clear_config([:instance, :public], false)
-
- test_missing_oauth_check_definition_failure(
- "/test/api/missing_oauth_check_definition",
- "This resource requires authentication."
- )
- end
-
- test "succeeds with dropped :user if served via :api on public instance" do
- %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
-
- assert %{"user_id" => nil} ==
- conn
- |> get("/test/api/missing_oauth_check_definition")
- |> json_response(200)
- end
- end
-end
diff --git a/test/web/masto_fe_controller_test.exs b/test/web/masto_fe_controller_test.exs
@@ -1,85 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MastoFEController do
- use Pleroma.Web.ConnCase
-
- alias Pleroma.Config
- alias Pleroma.User
-
- import Pleroma.Factory
-
- setup do: clear_config([:instance, :public])
-
- test "put settings", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"]))
- |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
-
- assert _result = json_response(conn, 200)
-
- user = User.get_cached_by_ap_id(user.ap_id)
- assert user.mastofe_settings == %{"programming" => "socks"}
- end
-
- describe "index/2 redirections" do
- setup %{conn: conn} do
- session_opts = [
- store: :cookie,
- key: "_test",
- signing_salt: "cooldude"
- ]
-
- conn =
- conn
- |> Plug.Session.call(Plug.Session.init(session_opts))
- |> fetch_session()
-
- test_path = "/web/statuses/test"
- %{conn: conn, path: test_path}
- end
-
- test "redirects not logged-in users to the login page", %{conn: conn, path: path} do
- conn = get(conn, path)
-
- assert conn.status == 302
- assert redirected_to(conn) == "/web/login"
- end
-
- test "redirects not logged-in users to the login page on private instances", %{
- conn: conn,
- path: path
- } do
- Config.put([:instance, :public], false)
-
- conn = get(conn, path)
-
- assert conn.status == 302
- assert redirected_to(conn) == "/web/login"
- end
-
- test "does not redirect logged in users to the login page", %{conn: conn, path: path} do
- token = insert(:oauth_token, scopes: ["read"])
-
- conn =
- conn
- |> assign(:user, token.user)
- |> assign(:token, token)
- |> get(path)
-
- assert conn.status == 200
- end
-
- test "saves referer path to session", %{conn: conn, path: path} do
- conn = get(conn, path)
- return_to = Plug.Conn.get_session(conn, :return_to)
-
- assert return_to == path
- end
- end
-end
diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs
@@ -1,529 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
- alias Pleroma.Repo
- alias Pleroma.User
-
- use Pleroma.Web.ConnCase
-
- import Mock
- import Pleroma.Factory
-
- setup do: clear_config([:instance, :max_account_fields])
-
- describe "updating credentials" do
- setup do: oauth_access(["write:accounts"])
- setup :request_content_type
-
- test "sets user settings in a generic way", %{conn: conn} do
- res_conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- "pleroma_settings_store" => %{
- pleroma_fe: %{
- theme: "bla"
- }
- }
- })
-
- assert user_data = json_response_and_validate_schema(res_conn, 200)
- assert user_data["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}}
-
- user = Repo.get(User, user_data["id"])
-
- res_conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/accounts/update_credentials", %{
- "pleroma_settings_store" => %{
- masto_fe: %{
- theme: "bla"
- }
- }
- })
-
- assert user_data = json_response_and_validate_schema(res_conn, 200)
-
- assert user_data["pleroma"]["settings_store"] ==
- %{
- "pleroma_fe" => %{"theme" => "bla"},
- "masto_fe" => %{"theme" => "bla"}
- }
-
- user = Repo.get(User, user_data["id"])
-
- clear_config([:instance, :federating], true)
-
- with_mock Pleroma.Web.Federator,
- publish: fn _activity -> :ok end do
- res_conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/accounts/update_credentials", %{
- "pleroma_settings_store" => %{
- masto_fe: %{
- theme: "blub"
- }
- }
- })
-
- assert user_data = json_response_and_validate_schema(res_conn, 200)
-
- assert user_data["pleroma"]["settings_store"] ==
- %{
- "pleroma_fe" => %{"theme" => "bla"},
- "masto_fe" => %{"theme" => "blub"}
- }
-
- assert_called(Pleroma.Web.Federator.publish(:_))
- end
- end
-
- test "updates the user's bio", %{conn: conn} do
- user2 = insert(:user)
-
- raw_bio = "I drink #cofe with @#{user2.nickname}\n\nsuya.."
-
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
-
- assert user_data["note"] ==
- ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a class="u-url mention" data-user="#{
- user2.id
- }" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..)
-
- assert user_data["source"]["note"] == raw_bio
-
- user = Repo.get(User, user_data["id"])
-
- assert user.raw_bio == raw_bio
- end
-
- test "updates the user's locking status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["locked"] == true
- end
-
- test "updates the user's chat acceptance status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{accepts_chat_messages: "false"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["accepts_chat_messages"] == false
- end
-
- test "updates the user's allow_following_move", %{user: user, conn: conn} do
- assert user.allow_following_move == true
-
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{allow_following_move: "false"})
-
- assert refresh_record(user).allow_following_move == false
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["allow_following_move"] == false
- end
-
- test "updates the user's default scope", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "unlisted"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["privacy"] == "unlisted"
- end
-
- test "updates the user's privacy", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{source: %{privacy: "unlisted"}})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["privacy"] == "unlisted"
- end
-
- test "updates the user's hide_followers status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_followers"] == true
- end
-
- test "updates the user's discoverable status", %{conn: conn} do
- assert %{"source" => %{"pleroma" => %{"discoverable" => true}}} =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{discoverable: "true"})
- |> json_response_and_validate_schema(:ok)
-
- assert %{"source" => %{"pleroma" => %{"discoverable" => false}}} =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{discoverable: "false"})
- |> json_response_and_validate_schema(:ok)
- end
-
- test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do
- conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- hide_followers_count: "true",
- hide_follows_count: "true"
- })
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_followers_count"] == true
- assert user_data["pleroma"]["hide_follows_count"] == true
- end
-
- test "updates the user's skip_thread_containment option", %{user: user, conn: conn} do
- response =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"})
- |> json_response_and_validate_schema(200)
-
- assert response["pleroma"]["skip_thread_containment"] == true
- assert refresh_record(user).skip_thread_containment
- end
-
- test "updates the user's hide_follows status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_follows: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_follows"] == true
- end
-
- test "updates the user's hide_favorites status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_favorites: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["pleroma"]["hide_favorites"] == true
- end
-
- test "updates the user's show_role status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{show_role: "false"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["pleroma"]["show_role"] == false
- end
-
- test "updates the user's no_rich_text status", %{conn: conn} do
- conn = patch(conn, "/api/v1/accounts/update_credentials", %{no_rich_text: "true"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["source"]["pleroma"]["no_rich_text"] == true
- end
-
- test "updates the user's name", %{conn: conn} do
- conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"})
-
- assert user_data = json_response_and_validate_schema(conn, 200)
- assert user_data["display_name"] == "markorepairs"
-
- update_activity = Repo.one(Pleroma.Activity)
- assert update_activity.data["type"] == "Update"
- assert update_activity.data["object"]["name"] == "markorepairs"
- end
-
- test "updates the user's avatar", %{user: user, conn: conn} do
- new_avatar = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- assert user.avatar == %{}
-
- res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
-
- assert user_response = json_response_and_validate_schema(res, 200)
- assert user_response["avatar"] != User.avatar_url(user)
-
- user = User.get_by_id(user.id)
- refute user.avatar == %{}
-
- # Also resets it
- _res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => ""})
-
- user = User.get_by_id(user.id)
- assert user.avatar == nil
- end
-
- test "updates the user's banner", %{user: user, conn: conn} do
- new_header = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
-
- assert user_response = json_response_and_validate_schema(res, 200)
- assert user_response["header"] != User.banner_url(user)
-
- # Also resets it
- _res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => ""})
-
- user = User.get_by_id(user.id)
- assert user.banner == nil
- end
-
- test "updates the user's background", %{conn: conn, user: user} do
- new_header = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- res =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- "pleroma_background_image" => new_header
- })
-
- assert user_response = json_response_and_validate_schema(res, 200)
- assert user_response["pleroma"]["background_image"]
- #
- # Also resets it
- _res =
- patch(conn, "/api/v1/accounts/update_credentials", %{"pleroma_background_image" => ""})
-
- user = User.get_by_id(user.id)
- assert user.background == nil
- end
-
- test "requires 'write:accounts' permission" do
- token1 = insert(:oauth_token, scopes: ["read"])
- token2 = insert(:oauth_token, scopes: ["write", "follow"])
-
- for token <- [token1, token2] do
- conn =
- build_conn()
- |> put_req_header("content-type", "multipart/form-data")
- |> put_req_header("authorization", "Bearer #{token.token}")
- |> patch("/api/v1/accounts/update_credentials", %{})
-
- if token == token1 do
- assert %{"error" => "Insufficient permissions: write:accounts."} ==
- json_response_and_validate_schema(conn, 403)
- else
- assert json_response_and_validate_schema(conn, 200)
- end
- end
- end
-
- test "updates profile emojos", %{user: user, conn: conn} do
- note = "*sips :blank:*"
- name = "I am :firefox:"
-
- ret_conn =
- patch(conn, "/api/v1/accounts/update_credentials", %{
- "note" => note,
- "display_name" => name
- })
-
- assert json_response_and_validate_schema(ret_conn, 200)
-
- conn = get(conn, "/api/v1/accounts/#{user.id}")
-
- assert user_data = json_response_and_validate_schema(conn, 200)
-
- assert user_data["note"] == note
- assert user_data["display_name"] == name
- assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user_data["emojis"]
- end
-
- test "update fields", %{conn: conn} do
- fields = [
- %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>"},
- %{"name" => "link.io", "value" => "cofe.io"}
- ]
-
- account_data =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(200)
-
- assert account_data["fields"] == [
- %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"},
- %{
- "name" => "link.io",
- "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)
- }
- ]
-
- assert account_data["source"]["fields"] == [
- %{
- "name" => "<a href=\"http://google.com\">foo</a>",
- "value" => "<script>bar</script>"
- },
- %{"name" => "link.io", "value" => "cofe.io"}
- ]
- end
-
- test "emojis in fields labels", %{conn: conn} do
- fields = [
- %{"name" => ":firefox:", "value" => "is best 2hu"},
- %{"name" => "they wins", "value" => ":blank:"}
- ]
-
- account_data =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(200)
-
- assert account_data["fields"] == [
- %{"name" => ":firefox:", "value" => "is best 2hu"},
- %{"name" => "they wins", "value" => ":blank:"}
- ]
-
- assert account_data["source"]["fields"] == [
- %{"name" => ":firefox:", "value" => "is best 2hu"},
- %{"name" => "they wins", "value" => ":blank:"}
- ]
-
- assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = account_data["emojis"]
- end
-
- test "update fields via x-www-form-urlencoded", %{conn: conn} do
- fields =
- [
- "fields_attributes[1][name]=link",
- "fields_attributes[1][value]=http://cofe.io",
- "fields_attributes[0][name]=foo",
- "fields_attributes[0][value]=bar"
- ]
- |> Enum.join("&")
-
- account =
- conn
- |> put_req_header("content-type", "application/x-www-form-urlencoded")
- |> patch("/api/v1/accounts/update_credentials", fields)
- |> json_response_and_validate_schema(200)
-
- assert account["fields"] == [
- %{"name" => "foo", "value" => "bar"},
- %{
- "name" => "link",
- "value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>)
- }
- ]
-
- assert account["source"]["fields"] == [
- %{"name" => "foo", "value" => "bar"},
- %{"name" => "link", "value" => "http://cofe.io"}
- ]
- end
-
- test "update fields with empty name", %{conn: conn} do
- fields = [
- %{"name" => "foo", "value" => ""},
- %{"name" => "", "value" => "bar"}
- ]
-
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(200)
-
- assert account["fields"] == [
- %{"name" => "foo", "value" => ""}
- ]
- end
-
- test "update fields when invalid request", %{conn: conn} do
- name_limit = Pleroma.Config.get([:instance, :account_field_name_length])
- value_limit = Pleroma.Config.get([:instance, :account_field_value_length])
-
- long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join()
- long_value = Enum.map(0..value_limit, fn _ -> "x" end) |> Enum.join()
-
- fields = [%{"name" => "foo", "value" => long_value}]
-
- assert %{"error" => "Invalid request"} ==
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
-
- fields = [%{"name" => long_name, "value" => "bar"}]
-
- assert %{"error" => "Invalid request"} ==
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
-
- Pleroma.Config.put([:instance, :max_account_fields], 1)
-
- fields = [
- %{"name" => "foo", "value" => "bar"},
- %{"name" => "link", "value" => "cofe.io"}
- ]
-
- assert %{"error" => "Invalid request"} ==
- conn
- |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
- |> json_response_and_validate_schema(403)
- end
- end
-
- describe "Mark account as bot" do
- setup do: oauth_access(["write:accounts"])
- setup :request_content_type
-
- test "changing actor_type to Service makes account a bot", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Service"})
- |> json_response_and_validate_schema(200)
-
- assert account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Service"
- end
-
- test "changing actor_type to Person makes account a human", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Person"})
- |> json_response_and_validate_schema(200)
-
- refute account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Person"
- end
-
- test "changing actor_type to Application causes error", %{conn: conn} do
- response =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Application"})
- |> json_response_and_validate_schema(403)
-
- assert %{"error" => "Invalid request"} == response
- end
-
- test "changing bot field to true changes actor_type to Service", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{bot: "true"})
- |> json_response_and_validate_schema(200)
-
- assert account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Service"
- end
-
- test "changing bot field to false changes actor_type to Person", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{bot: "false"})
- |> json_response_and_validate_schema(200)
-
- refute account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Person"
- end
-
- test "actor_type field has a higher priority than bot", %{conn: conn} do
- account =
- conn
- |> patch("/api/v1/accounts/update_credentials", %{
- actor_type: "Person",
- bot: "true"
- })
- |> json_response_and_validate_schema(200)
-
- refute account["bot"]
- assert account["source"]["pleroma"]["actor_type"] == "Person"
- end
- end
-end
diff --git a/test/web/mongooseim/mongoose_im_controller_test.exs b/test/web/mongooseim/mongoose_im_controller_test.exs
@@ -1,81 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.MongooseIMController do
- use Pleroma.Web.ConnCase
- import Pleroma.Factory
-
- test "/user_exists", %{conn: conn} do
- _user = insert(:user, nickname: "lain")
- _remote_user = insert(:user, nickname: "alice", local: false)
- _deactivated_user = insert(:user, nickname: "konata", deactivated: true)
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "lain")
- |> json_response(200)
-
- assert res == true
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "alice")
- |> json_response(404)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "bob")
- |> json_response(404)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :user_exists), user: "konata")
- |> json_response(404)
-
- assert res == false
- end
-
- test "/check_password", %{conn: conn} do
- user = insert(:user, password_hash: Pbkdf2.hash_pwd_salt("cool"))
-
- _deactivated_user =
- insert(:user,
- nickname: "konata",
- deactivated: true,
- password_hash: Pbkdf2.hash_pwd_salt("cool")
- )
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "cool")
- |> json_response(200)
-
- assert res == true
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "uncool")
- |> json_response(403)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: "konata", pass: "cool")
- |> json_response(404)
-
- assert res == false
-
- res =
- conn
- |> get(mongoose_im_path(conn, :check_password), user: "nobody", pass: "cool")
- |> json_response(404)
-
- assert res == false
- end
-end
diff --git a/test/web/pleroma_api/views/chat/message_reference_view_test.exs b/test/web/pleroma_api/views/chat/message_reference_view_test.exs
@@ -1,72 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PleromaAPI.Chat.MessageReferenceViewTest do
- use Pleroma.DataCase
-
- alias Pleroma.Chat
- alias Pleroma.Chat.MessageReference
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
-
- import Pleroma.Factory
-
- test "it displays a chat message" do
- user = insert(:user)
- recipient = insert(:user)
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
- {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "kippis :firefox:")
-
- chat = Chat.get(user.id, recipient.ap_id)
-
- object = Object.normalize(activity)
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- chat_message = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
-
- assert chat_message[:id] == cm_ref.id
- assert chat_message[:content] == "kippis :firefox:"
- assert chat_message[:account_id] == user.id
- assert chat_message[:chat_id]
- assert chat_message[:created_at]
- assert chat_message[:unread] == false
- assert match?([%{shortcode: "firefox"}], chat_message[:emojis])
-
- clear_config([:rich_media, :enabled], true)
-
- Tesla.Mock.mock(fn
- %{url: "https://example.com/ogp"} ->
- %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
- end)
-
- {:ok, activity} =
- CommonAPI.post_chat_message(recipient, user, "gkgkgk https://example.com/ogp",
- media_id: upload.id
- )
-
- object = Object.normalize(activity)
-
- cm_ref = MessageReference.for_chat_and_object(chat, object)
-
- chat_message_two = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
-
- assert chat_message_two[:id] == cm_ref.id
- assert chat_message_two[:content] == object.data["content"]
- assert chat_message_two[:account_id] == recipient.id
- assert chat_message_two[:chat_id] == chat_message[:chat_id]
- assert chat_message_two[:attachment]
- assert chat_message_two[:unread] == true
- assert chat_message_two[:card]
- end
-end
diff --git a/test/web/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs
@@ -1,31 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.FederatingPlugTest do
- use Pleroma.Web.ConnCase
-
- setup do: clear_config([:instance, :federating])
-
- test "returns and halt the conn when federating is disabled" do
- Pleroma.Config.put([:instance, :federating], false)
-
- conn =
- build_conn()
- |> Pleroma.Web.FederatingPlug.call(%{})
-
- assert conn.status == 404
- assert conn.halted
- end
-
- test "does nothing when federating is enabled" do
- Pleroma.Config.put([:instance, :federating], true)
-
- conn =
- build_conn()
- |> Pleroma.Web.FederatingPlug.call(%{})
-
- refute conn.status
- refute conn.halted
- end
-end
diff --git a/test/web/plugs/plug_test.exs b/test/web/plugs/plug_test.exs
@@ -1,91 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.PlugTest do
- @moduledoc "Tests for the functionality added via `use Pleroma.Web, :plug`"
-
- alias Pleroma.Plugs.ExpectAuthenticatedCheckPlug
- alias Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug
- alias Pleroma.Plugs.PlugHelper
-
- import Mock
-
- use Pleroma.Web.ConnCase
-
- describe "when plug is skipped, " do
- setup_with_mocks(
- [
- {ExpectPublicOrAuthenticatedCheckPlug, [:passthrough], []}
- ],
- %{conn: conn}
- ) do
- conn = ExpectPublicOrAuthenticatedCheckPlug.skip_plug(conn)
- %{conn: conn}
- end
-
- test "it neither adds plug to called plugs list nor calls `perform/2`, " <>
- "regardless of :if_func / :unless_func options",
- %{conn: conn} do
- for opts <- [%{}, %{if_func: fn _ -> true end}, %{unless_func: fn _ -> false end}] do
- ret_conn = ExpectPublicOrAuthenticatedCheckPlug.call(conn, opts)
-
- refute called(ExpectPublicOrAuthenticatedCheckPlug.perform(:_, :_))
- refute PlugHelper.plug_called?(ret_conn, ExpectPublicOrAuthenticatedCheckPlug)
- end
- end
- end
-
- describe "when plug is NOT skipped, " do
- setup_with_mocks([{ExpectAuthenticatedCheckPlug, [:passthrough], []}]) do
- :ok
- end
-
- test "with no pre-run checks, adds plug to called plugs list and calls `perform/2`", %{
- conn: conn
- } do
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{})
-
- assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
- assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
- end
-
- test "when :if_func option is given, calls the plug only if provided function evals tru-ish",
- %{conn: conn} do
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{if_func: fn _ -> false end})
-
- refute called(ExpectAuthenticatedCheckPlug.perform(:_, :_))
- refute PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
-
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{if_func: fn _ -> true end})
-
- assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
- assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
- end
-
- test "if :unless_func option is given, calls the plug only if provided function evals falsy",
- %{conn: conn} do
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{unless_func: fn _ -> true end})
-
- refute called(ExpectAuthenticatedCheckPlug.perform(:_, :_))
- refute PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
-
- ret_conn = ExpectAuthenticatedCheckPlug.call(conn, %{unless_func: fn _ -> false end})
-
- assert called(ExpectAuthenticatedCheckPlug.perform(ret_conn, :_))
- assert PlugHelper.plug_called?(ret_conn, ExpectAuthenticatedCheckPlug)
- end
-
- test "allows a plug to be called multiple times (even if it's in called plugs list)", %{
- conn: conn
- } do
- conn = ExpectAuthenticatedCheckPlug.call(conn, %{an_option: :value1})
- assert called(ExpectAuthenticatedCheckPlug.perform(conn, %{an_option: :value1}))
-
- assert PlugHelper.plug_called?(conn, ExpectAuthenticatedCheckPlug)
-
- conn = ExpectAuthenticatedCheckPlug.call(conn, %{an_option: :value2})
- assert called(ExpectAuthenticatedCheckPlug.perform(conn, %{an_option: :value2}))
- end
- end
-end
diff --git a/test/web/rich_media/aws_signed_url_test.exs b/test/web/rich_media/aws_signed_url_test.exs
@@ -1,82 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.RichMedia.TTL.AwsSignedUrlTest do
- use ExUnit.Case, async: true
-
- test "s3 signed url is parsed correct for expiration time" do
- url = "https://pleroma.social/amz"
-
- {:ok, timestamp} =
- Timex.now()
- |> DateTime.truncate(:second)
- |> Timex.format("{ISO:Basic:Z}")
-
- # in seconds
- valid_till = 30
-
- metadata = construct_metadata(timestamp, valid_till, url)
-
- expire_time =
- Timex.parse!(timestamp, "{ISO:Basic:Z}") |> Timex.to_unix() |> Kernel.+(valid_till)
-
- assert {:ok, expire_time} == Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl.ttl(metadata, url)
- end
-
- test "s3 signed url is parsed and correct ttl is set for rich media" do
- url = "https://pleroma.social/amz"
-
- {:ok, timestamp} =
- Timex.now()
- |> DateTime.truncate(:second)
- |> Timex.format("{ISO:Basic:Z}")
-
- # in seconds
- valid_till = 30
-
- metadata = construct_metadata(timestamp, valid_till, url)
-
- body = """
- <meta name="twitter:card" content="Pleroma" />
- <meta name="twitter:site" content="Pleroma" />
- <meta name="twitter:title" content="Pleroma" />
- <meta name="twitter:description" content="Pleroma" />
- <meta name="twitter:image" content="#{Map.get(metadata, :image)}" />
- """
-
- Tesla.Mock.mock(fn
- %{
- method: :get,
- url: "https://pleroma.social/amz"
- } ->
- %Tesla.Env{status: 200, body: body}
- end)
-
- Cachex.put(:rich_media_cache, url, metadata)
-
- Pleroma.Web.RichMedia.Parser.set_ttl_based_on_image(metadata, url)
-
- {:ok, cache_ttl} = Cachex.ttl(:rich_media_cache, url)
-
- # as there is delay in setting and pulling the data from cache we ignore 1 second
- # make it 2 seconds for flakyness
- assert_in_delta(valid_till * 1000, cache_ttl, 2000)
- end
-
- defp construct_s3_url(timestamp, valid_till) do
- "https://pleroma.s3.ap-southeast-1.amazonaws.com/sachin%20%281%29%20_a%20-%25%2Aasdasd%20BNN%20bnnn%20.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIBLWWK6RGDQXDLJQ%2F20190716%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=#{
- timestamp
- }&X-Amz-Expires=#{valid_till}&X-Amz-Signature=04ffd6b98634f4b1bbabc62e0fac4879093cd54a6eed24fe8eb38e8369526bbf&X-Amz-SignedHeaders=host"
- end
-
- defp construct_metadata(timestamp, valid_till, url) do
- %{
- image: construct_s3_url(timestamp, valid_till),
- site: "Pleroma",
- title: "Pleroma",
- description: "Pleroma",
- url: url
- }
- end
-end