forked from AkkomaGang/akkoma
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
This commit is contained in:
commit
e154fcf525
10 changed files with 53 additions and 39 deletions
|
@ -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.
|
- 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:** 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:** 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>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
|
|
|
@ -725,10 +725,12 @@
|
||||||
timeout: 300_000
|
timeout: 300_000
|
||||||
]
|
]
|
||||||
|
|
||||||
|
private_instance? = :if_instance_is_private
|
||||||
|
|
||||||
config :pleroma, :restrict_unauthenticated,
|
config :pleroma, :restrict_unauthenticated,
|
||||||
timelines: %{local: false, federated: false},
|
timelines: %{local: private_instance?, federated: private_instance?},
|
||||||
profiles: %{local: false, remote: false},
|
profiles: %{local: private_instance?, remote: private_instance?},
|
||||||
activities: %{local: false, remote: false}
|
activities: %{local: private_instance?, remote: private_instance?}
|
||||||
|
|
||||||
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false
|
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ 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_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.
|
* `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.
|
* `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`.
|
* `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.
|
* `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``.
|
* `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).
|
* `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML).
|
||||||
|
@ -1051,6 +1051,8 @@ Restrict access for unauthenticated users to timelines (public and federated), u
|
||||||
* `local`
|
* `local`
|
||||||
* `remote`
|
* `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).
|
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
|
## Pleroma.Web.ApiSpec.CastAndValidate
|
||||||
|
|
|
@ -81,6 +81,16 @@ def delete(key) do
|
||||||
Application.delete_env(:pleroma, key)
|
Application.delete_env(:pleroma, key)
|
||||||
end
|
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_strategies, do: get([:auth, :oauth_consumer_strategies], [])
|
||||||
|
|
||||||
def oauth_consumer_enabled?, do: oauth_consumer_strategies() != []
|
def oauth_consumer_enabled?, do: oauth_consumer_strategies() != []
|
||||||
|
|
|
@ -311,10 +311,12 @@ def visible_for(%User{} = user, for_user) do
|
||||||
|
|
||||||
def visible_for(_, _), do: :invisible
|
def visible_for(_, _), do: :invisible
|
||||||
|
|
||||||
defp restrict_unauthenticated?(%User{local: local}) do
|
defp restrict_unauthenticated?(%User{local: true}) do
|
||||||
config_key = if local, do: :local, else: :remote
|
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
|
end
|
||||||
|
|
||||||
defp visible_account_status(user) do
|
defp visible_account_status(user) do
|
||||||
|
|
|
@ -59,12 +59,9 @@ def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible_for_user?(%{local: local} = activity, nil) do
|
def visible_for_user?(%{local: local} = activity, nil) do
|
||||||
cfg_key =
|
cfg_key = if local, do: :local, else: :remote
|
||||||
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,
|
do: false,
|
||||||
else: is_public?(activity)
|
else: is_public?(activity)
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
||||||
import Pleroma.Web.ControllerHelper,
|
import Pleroma.Web.ControllerHelper,
|
||||||
only: [add_link_headers: 2, add_link_headers: 3]
|
only: [add_link_headers: 2, add_link_headers: 3]
|
||||||
|
|
||||||
|
alias Pleroma.Config
|
||||||
alias Pleroma.Pagination
|
alias Pleroma.Pagination
|
||||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||||
alias Pleroma.Plugs.OAuthScopesPlug
|
alias Pleroma.Plugs.OAuthScopesPlug
|
||||||
|
@ -89,11 +90,11 @@ def direct(%{assigns: %{user: user}} = conn, params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict_unauthenticated?(true = _local_only) do
|
defp restrict_unauthenticated?(true = _local_only) do
|
||||||
Pleroma.Config.get([:restrict_unauthenticated, :timelines, :local])
|
Config.restrict_unauthenticated_access?(:timelines, :local)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict_unauthenticated?(_) do
|
defp restrict_unauthenticated?(_) do
|
||||||
Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated])
|
Config.restrict_unauthenticated_access?(:timelines, :federated)
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /api/v1/timelines/public
|
# GET /api/v1/timelines/public
|
||||||
|
|
|
@ -16,7 +16,7 @@ def generate_terms(params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_public_tag(acc, params) do
|
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
|
acc
|
||||||
else
|
else
|
||||||
Map.put(acc, @public_url, public_timeline(params))
|
Map.put(acc, @public_url, public_timeline(params))
|
||||||
|
|
|
@ -445,6 +445,23 @@ defp ensure_authenticated_access(base_uri) do
|
||||||
assert length(json_response(res_conn, 200)) == 2
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
end
|
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", %{
|
test "with `%{local: true, federated: true}`, returns 403 for unauthenticated users", %{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
base_uri: base_uri,
|
base_uri: base_uri,
|
||||||
|
|
|
@ -12,16 +12,8 @@ defmodule Pleroma.Web.Preload.Providers.TimelineTest do
|
||||||
@public_url "/api/v1/timelines/public"
|
@public_url "/api/v1/timelines/public"
|
||||||
|
|
||||||
describe "unauthenticated timeliness when restricted" do
|
describe "unauthenticated timeliness when restricted" do
|
||||||
setup do
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||||
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||||
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{local: true, federated: true})
|
|
||||||
|
|
||||||
on_exit(fn ->
|
|
||||||
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
|
|
||||||
end)
|
|
||||||
|
|
||||||
:ok
|
|
||||||
end
|
|
||||||
|
|
||||||
test "return nothing" do
|
test "return nothing" do
|
||||||
tl_data = Timelines.generate_terms(%{})
|
tl_data = Timelines.generate_terms(%{})
|
||||||
|
@ -31,20 +23,10 @@ test "return nothing" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "unauthenticated timeliness when unrestricted" do
|
describe "unauthenticated timeliness when unrestricted" do
|
||||||
setup do
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :local], false)
|
||||||
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
|
setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], false)
|
||||||
|
|
||||||
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{
|
setup do: {:ok, user: insert(:user)}
|
||||||
local: false,
|
|
||||||
federated: false
|
|
||||||
})
|
|
||||||
|
|
||||||
on_exit(fn ->
|
|
||||||
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
|
|
||||||
end)
|
|
||||||
|
|
||||||
{:ok, user: insert(:user)}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns the timeline when not restricted" do
|
test "returns the timeline when not restricted" do
|
||||||
assert Timelines.generate_terms(%{})
|
assert Timelines.generate_terms(%{})
|
||||||
|
|
Loading…
Reference in a new issue