logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma
commit: e154fcf5258879c68fd7bd9fddd56d3dcb787826
parent: 1f2aad6fda22a3af8b475b5e4a01eae95a3438da
Author: lain <lain@soykaf.club>
Date:   Mon, 17 Aug 2020 12:26:53 +0000

Merge branch '2046-default-restrict-unauthenticated-basing-on-instance-privacy' into 'develop'

[#2046] Defaulted pleroma/restrict_unauthenticated basing on instance privacy

Closes #2046

See merge request pleroma/pleroma!2890

Diffstat:

MCHANGELOG.md1+
Mconfig/config.exs8+++++---
Mdocs/configuration/cheatsheet.md6++++--
Mlib/pleroma/config.ex10++++++++++
Mlib/pleroma/user.ex8+++++---
Mlib/pleroma/web/activity_pub/visibility.ex7++-----
Mlib/pleroma/web/mastodon_api/controllers/timeline_controller.ex5+++--
Mlib/pleroma/web/preload/timelines.ex2+-
Mtest/web/mastodon_api/controllers/timeline_controller_test.exs17+++++++++++++++++
Mtest/web/preload/timeline_test.exs28+++++-----------------------
10 files changed, 53 insertions(+), 39 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Configuration: `:media_proxy, whitelist` format changed to host with scheme (e.g. `http://example.com` instead of `example.com`). Domain format is deprecated. - **Breaking:** Configuration: `:instance, welcome_user_nickname` moved to `:welcome, :direct_message, :sender_nickname`, `:instance, :welcome_message` moved to `:welcome, :direct_message, :message`. Old config namespace is deprecated. - **Breaking:** LDAP: Fallback to local database authentication has been removed for security reasons and lack of a mechanism to ensure the passwords are synchronized when LDAP passwords are updated. +- **Breaking** Changed defaults for `:restrict_unauthenticated` so that when `:instance, :public` is set to `false` then all `:restrict_unauthenticated` items be effectively set to `true`. If you'd like to allow unauthenticated access to specific API endpoints on a private instance, please explicitly set `:restrict_unauthenticated` to non-default value in `config/prod.secret.exs`. <details> <summary>API Changes</summary> diff --git a/config/config.exs b/config/config.exs @@ -725,10 +725,12 @@ config :pleroma, :hackney_pools, timeout: 300_000 ] +private_instance? = :if_instance_is_private + config :pleroma, :restrict_unauthenticated, - timelines: %{local: false, federated: false}, - profiles: %{local: false, remote: false}, - activities: %{local: false, remote: false} + timelines: %{local: private_instance?, federated: private_instance?}, + profiles: %{local: private_instance?, remote: private_instance?}, + activities: %{local: private_instance?, remote: private_instance?} config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md @@ -38,8 +38,8 @@ To add configuration to your config file, you can copy it from the base config. * `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes. * `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it. * `allow_relay`: Enable Pleroma’s Relay, which makes it possible to follow a whole instance. -* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. See also: `restrict_unauthenticated`. -* `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send. +* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. Note that there is a dependent setting restricting or allowing unauthenticated access to specific resources, see `restrict_unauthenticated` for more details. +* `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``. * `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML). * `extended_nickname_format`: Set to `true` to use extended local nicknames format (allows underscores/dashes). This will break federation with @@ -1051,6 +1051,8 @@ Restrict access for unauthenticated users to timelines (public and federated), u * `local` * `remote` +Note: when `:instance, :public` is set to `false`, all `:restrict_unauthenticated` items be effectively set to `true` by default. If you'd like to allow unauthenticated access to specific API endpoints on a private instance, please explicitly set `:restrict_unauthenticated` to non-default value in `config/prod.secret.exs`. + Note: setting `restrict_unauthenticated/timelines/local` to `true` has no practical sense if `restrict_unauthenticated/timelines/federated` is set to `false` (since local public activities will still be delivered to unauthenticated users as part of federated timeline). ## Pleroma.Web.ApiSpec.CastAndValidate diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex @@ -81,6 +81,16 @@ defmodule Pleroma.Config do Application.delete_env(:pleroma, key) end + def restrict_unauthenticated_access?(resource, kind) do + setting = get([:restrict_unauthenticated, resource, kind]) + + if setting in [nil, :if_instance_is_private] do + !get!([:instance, :public]) + else + setting + end + end + def oauth_consumer_strategies, do: get([:auth, :oauth_consumer_strategies], []) def oauth_consumer_enabled?, do: oauth_consumer_strategies() != [] diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex @@ -311,10 +311,12 @@ defmodule Pleroma.User do def visible_for(_, _), do: :invisible - defp restrict_unauthenticated?(%User{local: local}) do - config_key = if local, do: :local, else: :remote + defp restrict_unauthenticated?(%User{local: true}) do + Config.restrict_unauthenticated_access?(:profiles, :local) + end - Config.get([:restrict_unauthenticated, :profiles, config_key], false) + defp restrict_unauthenticated?(%User{local: _}) do + Config.restrict_unauthenticated_access?(:profiles, :remote) end defp visible_account_status(user) do diff --git a/lib/pleroma/web/activity_pub/visibility.ex b/lib/pleroma/web/activity_pub/visibility.ex @@ -59,12 +59,9 @@ defmodule Pleroma.Web.ActivityPub.Visibility do end def visible_for_user?(%{local: local} = activity, nil) do - cfg_key = - if local, - do: :local, - else: :remote + cfg_key = if local, do: :local, else: :remote - if Pleroma.Config.get([:restrict_unauthenticated, :activities, cfg_key]), + if Pleroma.Config.restrict_unauthenticated_access?(:activities, cfg_key), do: false, else: is_public?(activity) end diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex @@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, add_link_headers: 3] + alias Pleroma.Config alias Pleroma.Pagination alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Plugs.OAuthScopesPlug @@ -89,11 +90,11 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do end defp restrict_unauthenticated?(true = _local_only) do - Pleroma.Config.get([:restrict_unauthenticated, :timelines, :local]) + Config.restrict_unauthenticated_access?(:timelines, :local) end defp restrict_unauthenticated?(_) do - Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated]) + Config.restrict_unauthenticated_access?(:timelines, :federated) end # GET /api/v1/timelines/public diff --git a/lib/pleroma/web/preload/timelines.ex b/lib/pleroma/web/preload/timelines.ex @@ -16,7 +16,7 @@ defmodule Pleroma.Web.Preload.Providers.Timelines do end def build_public_tag(acc, params) do - if Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated], true) do + if Pleroma.Config.restrict_unauthenticated_access?(:timelines, :federated) do acc else Map.put(acc, @public_url, public_timeline(params)) diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs @@ -445,6 +445,23 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do assert length(json_response(res_conn, 200)) == 2 end + test "with default settings on private instances, returns 403 for unauthenticated users", %{ + conn: conn, + base_uri: base_uri, + error_response: error_response + } do + clear_config([:instance, :public], false) + clear_config([:restrict_unauthenticated, :timelines]) + + for local <- [true, false] do + res_conn = get(conn, "#{base_uri}?local=#{local}") + + assert json_response(res_conn, :unauthorized) == error_response + end + + ensure_authenticated_access(base_uri) + end + test "with `%{local: true, federated: true}`, returns 403 for unauthenticated users", %{ conn: conn, base_uri: base_uri, diff --git a/test/web/preload/timeline_test.exs b/test/web/preload/timeline_test.exs @@ -12,16 +12,8 @@ defmodule Pleroma.Web.Preload.Providers.TimelineTest do @public_url "/api/v1/timelines/public" describe "unauthenticated timeliness when restricted" do - setup do - svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines]) - Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{local: true, federated: true}) - - on_exit(fn -> - Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config) - end) - - :ok - end + setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true) + setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true) test "return nothing" do tl_data = Timelines.generate_terms(%{}) @@ -31,20 +23,10 @@ defmodule Pleroma.Web.Preload.Providers.TimelineTest do end describe "unauthenticated timeliness when unrestricted" do - setup do - svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines]) + setup do: clear_config([:restrict_unauthenticated, :timelines, :local], false) + setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], false) - Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{ - local: false, - federated: false - }) - - on_exit(fn -> - Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config) - end) - - {:ok, user: insert(:user)} - end + setup do: {:ok, user: insert(:user)} test "returns the timeline when not restricted" do assert Timelines.generate_terms(%{})