diff --git a/.dockerignore b/.dockerignore index c5ef89b86..6b1879e62 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,7 +5,6 @@ CC-BY-SA-4.0 COPYING *file elixir_buildpack.config -docs/ test/ # Required to get version diff --git a/CHANGELOG.md b/CHANGELOG.md index b4e013cdd..3e22d7acb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Admin API: Return `total` when querying for reports - Mastodon API: Return `pleroma.direct_conversation_id` when creating a direct message (`POST /api/v1/statuses`) - Admin API: Return link alongside with token on password reset +- Admin API: Support authentication via `x-admin-token` HTTP header - Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`) - Mastodon API: `pleroma.thread_muted` to the Status entity - Mastodon API: Mark the direct conversation as read for the author when they send a new direct message @@ -42,6 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Static Frontend: Add the ability to render user profiles and notices server-side without requiring JS app. - Mix task to re-count statuses for all users (`mix pleroma.count_statuses`) - Support for `X-Forwarded-For` and similar HTTP headers which used by reverse proxies to pass a real user IP address to the backend. Must not be enabled unless your instance is behind at least one reverse proxy (such as Nginx, Apache HTTPD or Varnish Cache). +- MRF: New module which handles incoming posts based on their age. By default, all incoming posts that are older than 2 days will be unlisted and not shown to their followers.
API Changes @@ -80,6 +82,41 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Mastodon API: Inability to get some local users by nickname in `/api/v1/accounts/:id_or_nickname`
+## [1.1.6] - 2019-11-19 +### Fixed +- Not being able to log into to third party apps when the browser is logged into mastofe +- Email confirmation not being required even when enabled +- Mastodon API: conversations API crashing when one status is malformed + +### Bundled Pleroma-FE Changes +#### Added +- About page +- Meme arrows + +#### Fixed +- Image modal not closing unless clicked outside of image +- Attachment upload spinner not being centered +- Showing follow counters being 0 when they are actually hidden + +## [1.1.5] - 2019-11-09 +### Fixed +- Polls having different numbers in timelines/notifications/poll api endpoints due to cache desyncronization +- Pleroma API: OAuth token endpoint not being found when ".json" suffix is appended + +### Changed +- Frontend bundle updated to [044c9ad0](https://git.pleroma.social/pleroma/pleroma-fe/commit/044c9ad0562af059dd961d50961a3880fca9c642) + +## [1.1.4] - 2019-11-01 +### Fixed +- Added a migration that fills up empty user.info fields to prevent breakage after previous unsafe migrations. +- Failure to migrate from pre-1.0.0 versions +- Mastodon API: Notification stream not including follow notifications + +## [1.1.3] - 2019-10-25 +### Fixed +- Blocked users showing up in notifications collapsed as if they were muted +- `pleroma_ctl` not working on Debian's default shell + ## [1.1.2] - 2019-10-18 ### Fixed - `pleroma_ctl` trying to connect to a running instance when generating the config, which of course doesn't exist. diff --git a/config/config.exs b/config/config.exs index 75f463797..bf2b3f6e2 100644 --- a/config/config.exs +++ b/config/config.exs @@ -381,6 +381,10 @@ accept: [], reject: [] +config :pleroma, :mrf_object_age, + threshold: 172_800, + actions: [:delist, :strip_followers] + config :pleroma, :rich_media, enabled: true, ignore_hosts: [], diff --git a/docs/API/admin_api.md b/docs/API/admin_api.md index 9d914c9a6..f64983a90 100644 --- a/docs/API/admin_api.md +++ b/docs/API/admin_api.md @@ -235,14 +235,6 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret } ``` -## DEPRECATED `PATCH /api/pleroma/admin/users/:nickname/activation_status` - -### Active or deactivate a user - -- Params: - - `nickname` - - `status` BOOLEAN field, false value means deactivation. - ## `GET /api/pleroma/admin/users/:nickname_or_id` ### Retrive the details of a user diff --git a/docs/administration/CLI_tasks/database.md b/docs/administration/CLI_tasks/database.md index 484639231..3011646c8 100644 --- a/docs/administration/CLI_tasks/database.md +++ b/docs/administration/CLI_tasks/database.md @@ -2,6 +2,9 @@ Every command should be ran with a prefix, in case of OTP releases it is `./bin/pleroma_ctl database` and in case of source installs it's `mix pleroma.database`. +!!! danger + These mix tasks can take a long time to complete. Many of them were written to address specific database issues that happened because of bugs in migrations or other specific scenarios. Do not run these tasks "just in case" if everything is fine your instance. + ## Replace embedded objects with their references Replaces embedded objects with references to them in the `objects` table. Only needs to be ran once if the instance was created before Pleroma 1.0.5. The reason why this is not a migration is because it could significantly increase the database size after being ran, however after this `VACUUM FULL` will be able to reclaim about 20% (really depends on what is in the database, your mileage may vary) of the db size before the migration. diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index 7832f6962..07d9a1d45 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -41,6 +41,7 @@ You shouldn't edit the base config directly to avoid breakages and merge conflic * `Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`: Crawls attachments using their MediaProxy URLs so that the MediaProxy cache is primed. * `Pleroma.Web.ActivityPub.MRF.MentionPolicy`: Drops posts mentioning configurable users. (See [`:mrf_mention`](#mrf_mention)). * `Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`: Restricts activities to a configured set of vocabulary. (See [`:mrf_vocabulary`](#mrf_vocabulary)). + * `Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy`: Rejects or delists posts based on their age when received. (See [`:mrf_object_age`](#mrf_object_age)). * `public`: Makes the client API in authentificated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. * `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send. * `managed_config`: Whenether the config for pleroma-fe is configured in [:frontend_configurations](#frontend_configurations) or in ``static/config.json``. @@ -137,6 +138,13 @@ config :pleroma, :mrf_user_allowlist, "example.org": ["https://example.org/users/admin"] ``` +#### :mrf_object_age +* `threshold`: Required age (in seconds) of a post before actions are taken. +* `actions`: A list of actions to apply to the post: + * `:delist` removes the post from public timelines + * `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines + * `:reject` rejects the message entirely + ### :activitypub * ``unfollow_blocked``: Whether blocks result in people getting unfollowed * ``outgoing_blocks``: Whether to federate blocks to other instances @@ -648,7 +656,7 @@ Feel free to adjust the priv_dir and port number. Then you will have to create t ### :admin_token -Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the 'admin_token' parameter. Example: +Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the `admin_token` parameter or `x-admin-token` HTTP header. Example: ```elixir config :pleroma, :admin_token, "somerandomtoken" @@ -656,8 +664,14 @@ config :pleroma, :admin_token, "somerandomtoken" You can then do -```sh -curl "http://localhost:4000/api/pleroma/admin/invite_token?admin_token=somerandomtoken" +```shell +curl "http://localhost:4000/api/pleroma/admin/users/invites?admin_token=somerandomtoken" +``` + +or + +```shell +curl -H "X-Admin-Token: somerandomtoken" "http://localhost:4000/api/pleroma/admin/users/invites" ``` ### :auth diff --git a/lib/pleroma/plugs/admin_secret_authentication_plug.ex b/lib/pleroma/plugs/admin_secret_authentication_plug.ex index fdadd476e..49dea452d 100644 --- a/lib/pleroma/plugs/admin_secret_authentication_plug.ex +++ b/lib/pleroma/plugs/admin_secret_authentication_plug.ex @@ -16,14 +16,28 @@ def secret_token do def call(%{assigns: %{user: %User{}}} = conn, _), do: conn - def call(%{params: %{"admin_token" => admin_token}} = conn, _) do - if secret_token() && admin_token == secret_token() do - conn - |> assign(:user, %User{is_admin: true}) + def call(conn, _) do + if secret_token() do + authenticate(conn) else conn end end - def call(conn, _), do: conn + def authenticate(%{params: %{"admin_token" => admin_token}} = conn) do + if admin_token == secret_token() do + assign(conn, :user, %User{is_admin: true}) + else + conn + end + end + + def authenticate(conn) do + token = secret_token() + + case get_req_header(conn, "x-admin-token") do + [^token] -> assign(conn, :user, %User{is_admin: true}) + _ -> conn + end + end end diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex index fd004fcd2..11a5b7642 100644 --- a/lib/pleroma/plugs/oauth_plug.ex +++ b/lib/pleroma/plugs/oauth_plug.ex @@ -71,7 +71,7 @@ defp fetch_user_and_token(token) do ) # credo:disable-for-next-line Credo.Check.Readability.MaxLineLength - with %Token{user: %{deactivated: false} = user} = token_record <- Repo.one(query) do + with %Token{user: user} = token_record <- Repo.one(query) do {:ok, user, token_record} end end diff --git a/lib/pleroma/plugs/user_enabled_plug.ex b/lib/pleroma/plugs/user_enabled_plug.ex index fbb4bf115..8d102ee5b 100644 --- a/lib/pleroma/plugs/user_enabled_plug.ex +++ b/lib/pleroma/plugs/user_enabled_plug.ex @@ -10,9 +10,13 @@ def init(options) do options end - def call(%{assigns: %{user: %User{deactivated: true}}} = conn, _) do - conn - |> assign(:user, nil) + def call(%{assigns: %{user: %User{} = user}} = conn, _) do + if User.auth_active?(user) do + conn + else + conn + |> assign(:user, nil) + end end def call(conn, _) do diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f8c2db1e1..fcb1d5143 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -124,6 +124,9 @@ defmodule Pleroma.User do timestamps() end + @doc "Returns if the user should be allowed to authenticate" + def auth_active?(%User{deactivated: true}), do: false + def auth_active?(%User{confirmation_pending: true}), do: !Pleroma.Config.get([:instance, :account_activation_required]) diff --git a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex new file mode 100644 index 000000000..8b36c1021 --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex @@ -0,0 +1,101 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do + alias Pleroma.Config + alias Pleroma.User + alias Pleroma.Web.ActivityPub.MRF + + require Pleroma.Constants + + @moduledoc "Filter activities depending on their age" + @behaviour MRF + + defp check_date(%{"published" => published} = message) do + with %DateTime{} = now <- DateTime.utc_now(), + {:ok, %DateTime{} = then, _} <- DateTime.from_iso8601(published), + max_ttl <- Config.get([:mrf_object_age, :threshold]), + {:ttl, false} <- {:ttl, DateTime.diff(now, then) > max_ttl} do + {:ok, message} + else + {:ttl, true} -> + {:reject, nil} + + e -> + {:error, e} + end + end + + defp check_reject(message, actions) do + if :reject in actions do + {:reject, nil} + else + {:ok, message} + end + end + + defp check_delist(message, actions) do + if :delist in actions do + with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do + to = List.delete(message["to"], Pleroma.Constants.as_public()) ++ [user.follower_address] + cc = List.delete(message["cc"], user.follower_address) ++ [Pleroma.Constants.as_public()] + + message = + message + |> Map.put("to", to) + |> Map.put("cc", cc) + + {:ok, message} + else + # Unhandleable error: somebody is messing around, just drop the message. + _e -> + {:reject, nil} + end + else + {:ok, message} + end + end + + defp check_strip_followers(message, actions) do + if :strip_followers in actions do + with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do + to = List.delete(message["to"], user.follower_address) + cc = List.delete(message["cc"], user.follower_address) + + message = + message + |> Map.put("to", to) + |> Map.put("cc", cc) + + {:ok, message} + else + # Unhandleable error: somebody is messing around, just drop the message. + _e -> + {:reject, nil} + end + else + {:ok, message} + end + end + + @impl true + def filter(%{"type" => "Create", "published" => _} = message) do + with actions <- Config.get([:mrf_object_age, :actions]), + {:reject, _} <- check_date(message), + {:ok, message} <- check_reject(message, actions), + {:ok, message} <- check_delist(message, actions), + {:ok, message} <- check_strip_followers(message, actions) do + {:ok, message} + else + # check_date() is allowed to short-circuit the pipeline + e -> e + end + end + + @impl true + def filter(message), do: {:ok, message} + + @impl true + def describe, do: {:ok, %{}} +end diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 486b9f6a4..abcf46034 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -120,6 +120,12 @@ def raw_nodeinfo do banner: Config.get([:instance, :banner_upload_limit]), background: Config.get([:instance, :background_upload_limit]) }, + fieldsLimits: %{ + maxFields: Config.get([:instance, :max_account_fields]), + maxRemoteFields: Config.get([:instance, :max_remote_account_fields]), + nameLength: Config.get([:instance, :account_field_name_length]), + valueLength: Config.get([:instance, :account_field_value_length]) + }, accountActivationRequired: Config.get([:instance, :account_activation_required], false), invitesEnabled: Config.get([:instance, :invites_enabled], false), mailerEnabled: Config.get([Pleroma.Emails.Mailer, :enabled], false), diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 9eadb4591..12b676065 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -13,6 +13,7 @@ defmodule Pleroma.Web.Router do pipeline :oauth do plug(:fetch_session) plug(Pleroma.Plugs.OAuthPlug) + plug(Pleroma.Plugs.UserEnabledPlug) end pipeline :api do diff --git a/mix.lock b/mix.lock index d4a80df77..3a664287c 100644 --- a/mix.lock +++ b/mix.lock @@ -35,8 +35,8 @@ "ex_machina": {:hex, :ex_machina, "2.3.0", "92a5ad0a8b10ea6314b876a99c8c9e3f25f4dde71a2a835845b136b9adaf199a", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm"}, "ex_syslogger": {:git, "https://github.com/slashmili/ex_syslogger.git", "f3963399047af17e038897c69e20d552e6899e1d", [tag: "1.4.0"]}, "excoveralls": {:hex, :excoveralls, "0.11.2", "0c6f2c8db7683b0caa9d490fb8125709c54580b4255ffa7ad35f3264b075a643", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "fast_html": {:hex, :fast_html, "0.99.3", "e7ce6245fed0635f4719a31cc409091ed17b2091165a4a1cffbf2ceac77abbf4", [:make, :mix], [], "hexpm"}, - "fast_sanitize": {:hex, :fast_sanitize, "0.1.3", "e89a743b1679c344abdfcf79778d1499fbc599eca2d8a8cdfaf9ff520986fb72", [:mix], [{:fast_html, "~> 0.99", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "fast_html": {:hex, :fast_html, "0.99.4", "d80812664f0429607e1d880fba0ef04da87a2e4fa596701bcaae17953535695c", [:make, :mix], [], "hexpm"}, + "fast_sanitize": {:hex, :fast_sanitize, "0.1.4", "6c2e7203ca2f8275527a3021ba6e9d5d4ee213a47dc214a97c128737c9e56df1", [:mix], [{:fast_html, "~> 0.99", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "floki": {:hex, :floki, "0.23.0", "956ab6dba828c96e732454809fb0bd8d43ce0979b75f34de6322e73d4c917829", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm"}, "gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm"}, diff --git a/priv/static/index.html b/priv/static/index.html index f1a26cc95..2a6c7b036 100644 --- a/priv/static/index.html +++ b/priv/static/index.html @@ -1 +1 @@ -Pleroma
\ No newline at end of file +Pleroma
\ No newline at end of file diff --git a/priv/static/static/js/2.73375b727cef616c59b4.js b/priv/static/static/js/2.c96b30ae9f2d3f46f0ad.js similarity index 71% rename from priv/static/static/js/2.73375b727cef616c59b4.js rename to priv/static/static/js/2.c96b30ae9f2d3f46f0ad.js index ebfd9acbd..910d304d3 100644 Binary files a/priv/static/static/js/2.73375b727cef616c59b4.js and b/priv/static/static/js/2.c96b30ae9f2d3f46f0ad.js differ diff --git a/priv/static/static/js/2.73375b727cef616c59b4.js.map b/priv/static/static/js/2.c96b30ae9f2d3f46f0ad.js.map similarity index 99% rename from priv/static/static/js/2.73375b727cef616c59b4.js.map rename to priv/static/static/js/2.c96b30ae9f2d3f46f0ad.js.map index d2c864eb3..25e514a5b 100644 Binary files a/priv/static/static/js/2.73375b727cef616c59b4.js.map and b/priv/static/static/js/2.c96b30ae9f2d3f46f0ad.js.map differ diff --git a/priv/static/static/js/app.105d64a8fcdd6724ccde.js b/priv/static/static/js/app.105d64a8fcdd6724ccde.js deleted file mode 100644 index 9cb129d22..000000000 Binary files a/priv/static/static/js/app.105d64a8fcdd6724ccde.js and /dev/null differ diff --git a/priv/static/static/js/app.105d64a8fcdd6724ccde.js.map b/priv/static/static/js/app.105d64a8fcdd6724ccde.js.map deleted file mode 100644 index ab2588f48..000000000 Binary files a/priv/static/static/js/app.105d64a8fcdd6724ccde.js.map and /dev/null differ diff --git a/priv/static/static/js/app.d20ca27d22d74eb7bce0.js b/priv/static/static/js/app.d20ca27d22d74eb7bce0.js new file mode 100644 index 000000000..7abf2ec28 Binary files /dev/null and b/priv/static/static/js/app.d20ca27d22d74eb7bce0.js differ diff --git a/priv/static/static/js/app.d20ca27d22d74eb7bce0.js.map b/priv/static/static/js/app.d20ca27d22d74eb7bce0.js.map new file mode 100644 index 000000000..6c96ca5b2 Binary files /dev/null and b/priv/static/static/js/app.d20ca27d22d74eb7bce0.js.map differ diff --git a/priv/static/static/js/vendors~app.5c3fab032deb5f2793cb.js.map b/priv/static/static/js/vendors~app.5c3fab032deb5f2793cb.js.map deleted file mode 100644 index 5e7b10459..000000000 Binary files a/priv/static/static/js/vendors~app.5c3fab032deb5f2793cb.js.map and /dev/null differ diff --git a/priv/static/static/js/vendors~app.5c3fab032deb5f2793cb.js b/priv/static/static/js/vendors~app.76db8e4cdf29decd5cab.js similarity index 59% rename from priv/static/static/js/vendors~app.5c3fab032deb5f2793cb.js rename to priv/static/static/js/vendors~app.76db8e4cdf29decd5cab.js index db0f6a9a3..135bdebb3 100644 Binary files a/priv/static/static/js/vendors~app.5c3fab032deb5f2793cb.js and b/priv/static/static/js/vendors~app.76db8e4cdf29decd5cab.js differ diff --git a/priv/static/static/js/vendors~app.76db8e4cdf29decd5cab.js.map b/priv/static/static/js/vendors~app.76db8e4cdf29decd5cab.js.map new file mode 100644 index 000000000..6513c0a0b Binary files /dev/null and b/priv/static/static/js/vendors~app.76db8e4cdf29decd5cab.js.map differ diff --git a/priv/static/sw-pleroma.js b/priv/static/sw-pleroma.js index ec6185afc..276af8173 100644 Binary files a/priv/static/sw-pleroma.js and b/priv/static/sw-pleroma.js differ diff --git a/test/plugs/admin_secret_authentication_plug_test.exs b/test/plugs/admin_secret_authentication_plug_test.exs index c94a62c10..506b1f609 100644 --- a/test/plugs/admin_secret_authentication_plug_test.exs +++ b/test/plugs/admin_secret_authentication_plug_test.exs @@ -22,21 +22,39 @@ test "does nothing if a user is assigned", %{conn: conn} do assert conn == ret_conn end - test "with secret set and given in the 'admin_token' parameter, it assigns an admin user", %{ - conn: conn - } do - Pleroma.Config.put(:admin_token, "password123") + describe "when secret set it assigns an admin user" do + test "with `admin_token` query parameter", %{conn: conn} do + Pleroma.Config.put(:admin_token, "password123") - conn = - %{conn | params: %{"admin_token" => "wrong_password"}} - |> AdminSecretAuthenticationPlug.call(%{}) + conn = + %{conn | params: %{"admin_token" => "wrong_password"}} + |> AdminSecretAuthenticationPlug.call(%{}) - refute conn.assigns[:user] + refute conn.assigns[:user] - conn = - %{conn | params: %{"admin_token" => "password123"}} - |> AdminSecretAuthenticationPlug.call(%{}) + conn = + %{conn | params: %{"admin_token" => "password123"}} + |> AdminSecretAuthenticationPlug.call(%{}) - assert conn.assigns[:user].is_admin + assert conn.assigns[:user].is_admin + 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] + + conn = + conn + |> put_req_header("x-admin-token", "☕️") + |> AdminSecretAuthenticationPlug.call(%{}) + + assert conn.assigns[:user].is_admin + end end end diff --git a/test/plugs/user_enabled_plug_test.exs b/test/plugs/user_enabled_plug_test.exs index 996a7d77b..a4035bf0e 100644 --- a/test/plugs/user_enabled_plug_test.exs +++ b/test/plugs/user_enabled_plug_test.exs @@ -16,6 +16,23 @@ test "doesn't do anything if the user isn't set", %{conn: conn} do 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 + old = Pleroma.Config.get([:instance, :account_activation_required]) + 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 + + Pleroma.Config.put([:instance, :account_activation_required], old) + end + test "with a user that is deactivated, it removes that user", %{conn: conn} do user = insert(:user, deactivated: true) diff --git a/test/user_test.exs b/test/user_test.exs index 6b1b24ce5..8fdb6b25f 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1195,6 +1195,13 @@ test "auth_active?/1 works correctly" do refute User.auth_active?(local_user) assert User.auth_active?(confirmed_user) assert User.auth_active?(remote_user) + + # also shows unactive for deactivated users + + deactivated_but_confirmed = + insert(:user, local: true, confirmation_pending: false, deactivated: true) + + refute User.auth_active?(deactivated_but_confirmed) end describe "superuser?/1" do diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs new file mode 100644 index 000000000..643609da4 --- /dev/null +++ b/test/web/activity_pub/mrf/object_age_policy_test.exs @@ -0,0 +1,105 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do + use Pleroma.DataCase + alias Pleroma.Config + alias Pleroma.User + alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy + alias Pleroma.Web.ActivityPub.Visibility + + clear_config([:mrf_object_age]) do + Config.put(:mrf_object_age, + threshold: 172_800, + actions: [:delist, :strip_followers] + ) + end + + setup_all do + Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) + :ok + end + + describe "with reject action" do + test "it rejects an old post" do + Config.put([:mrf_object_age, :actions], [:reject]) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + + {:reject, _} = ObjectAgePolicy.filter(data) + end + + test "it allows a new post" do + Config.put([:mrf_object_age, :actions], [:reject]) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + + {:ok, _} = ObjectAgePolicy.filter(data) + end + end + + describe "with delist action" do + test "it delists an old post" do + Config.put([:mrf_object_age, :actions], [:delist]) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + + {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) + + {:ok, data} = ObjectAgePolicy.filter(data) + + assert Visibility.get_visibility(%{data: data}) == "unlisted" + end + + test "it allows a new post" do + Config.put([:mrf_object_age, :actions], [:delist]) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + + {:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"]) + + {:ok, ^data} = ObjectAgePolicy.filter(data) + end + end + + describe "with strip_followers action" do + test "it strips followers collections from an old post" do + Config.put([:mrf_object_age, :actions], [:strip_followers]) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + + {:ok, user} = User.get_or_fetch_by_ap_id(data["actor"]) + + {:ok, data} = ObjectAgePolicy.filter(data) + + refute user.follower_address in data["to"] + refute user.follower_address in data["cc"] + end + + test "it allows a new post" do + Config.put([:mrf_object_age, :actions], [:strip_followers]) + + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + + {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) + + {:ok, ^data} = ObjectAgePolicy.filter(data) + end + end +end diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/web/mastodon_api/controllers/filter_controller_test.exs index 5d5b56c8e..550689788 100644 --- a/test/web/mastodon_api/controllers/filter_controller_test.exs +++ b/test/web/mastodon_api/controllers/filter_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase alias Pleroma.Web.MastodonAPI.FilterView diff --git a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs index 9ad6a4fa7..ae5fee2bc 100644 --- a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs +++ b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do - use Pleroma.Web.ConnCase, async: true + use Pleroma.Web.ConnCase alias Pleroma.Repo alias Pleroma.ScheduledActivity diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index 6cc876602..9a574a38d 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -61,6 +61,33 @@ test "returns software.repository field in nodeinfo 2.1", %{conn: conn} do assert Pleroma.Application.repository() == result["software"]["repository"] end + test "returns fieldsLimits field", %{conn: conn} do + max_account_fields = Pleroma.Config.get([:instance, :max_account_fields]) + max_remote_account_fields = Pleroma.Config.get([:instance, :max_remote_account_fields]) + account_field_name_length = Pleroma.Config.get([:instance, :account_field_name_length]) + account_field_value_length = Pleroma.Config.get([:instance, :account_field_value_length]) + + Pleroma.Config.put([:instance, :max_account_fields], 10) + Pleroma.Config.put([:instance, :max_remote_account_fields], 15) + Pleroma.Config.put([:instance, :account_field_name_length], 255) + Pleroma.Config.put([:instance, :account_field_value_length], 2048) + + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) + + assert response["metadata"]["fieldsLimits"]["maxFields"] == 10 + assert response["metadata"]["fieldsLimits"]["maxRemoteFields"] == 15 + assert response["metadata"]["fieldsLimits"]["nameLength"] == 255 + assert response["metadata"]["fieldsLimits"]["valueLength"] == 2048 + + Pleroma.Config.put([:instance, :max_account_fields], max_account_fields) + Pleroma.Config.put([:instance, :max_remote_account_fields], max_remote_account_fields) + Pleroma.Config.put([:instance, :account_field_name_length], account_field_name_length) + Pleroma.Config.put([:instance, :account_field_value_length], account_field_value_length) + end + test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do option = Pleroma.Config.get([:instance, :safe_dm_mentions]) Pleroma.Config.put([:instance, :safe_dm_mentions], true)