Merge branch 'release/2.5.2' into mergeback/2.5.2
This commit is contained in:
commit
869f0d24a6
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -18,6 +18,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
### Removed
|
||||
- BREAKING: Support for passwords generated with `crypt(3)` (Gnu Social migration artifact)
|
||||
|
||||
## 2.5.2
|
||||
|
||||
### Security
|
||||
- `/proxy` endpoint now sets a Content-Security-Policy (sandbox)
|
||||
- WebSocket endpoint now respects unauthenticated restrictions for streams of public posts
|
||||
- OEmbed HTML tags are now filtered
|
||||
|
||||
### Changed
|
||||
- docs: Be more explicit about the level of compatibility of OTP releases
|
||||
- Set default background worker timeout to 15 minutes
|
||||
|
||||
### Fixed
|
||||
- Atom/RSS formatting (HTML truncation, published, missing summary)
|
||||
- Remove `static_fe` pipeline for `/users/:nickname/feed`
|
||||
- Stop oban from retrying if validating errors occur when processing incoming data
|
||||
- Make sure object refetching as used by already received polls follows MRF rules
|
||||
|
||||
### Removed
|
||||
- BREAKING: Support for passwords generated with `crypt(3)` (Gnu Social migration artifact)
|
||||
|
||||
## 2.5.1
|
||||
|
||||
### Added
|
||||
|
|
|
@ -25,6 +25,7 @@ defmodule Pleroma.Web.Streamer do
|
|||
def registry, do: @registry
|
||||
|
||||
@public_streams ["public", "public:local", "public:media", "public:local:media"]
|
||||
@local_streams ["public:local", "public:local:media"]
|
||||
@user_streams ["user", "user:notification", "direct", "user:pleroma_chat"]
|
||||
|
||||
@doc "Expands and authorizes a stream, and registers the process for streaming."
|
||||
|
@ -41,14 +42,37 @@ def get_topic_and_add_socket(stream, user, oauth_token, params \\ %{}) do
|
|||
end
|
||||
end
|
||||
|
||||
defp can_access_stream(user, oauth_token, kind) do
|
||||
with {_, true} <- {:restrict?, Config.restrict_unauthenticated_access?(:timelines, kind)},
|
||||
{_, %User{id: user_id}, %Token{user_id: user_id}} <- {:user, user, oauth_token},
|
||||
{_, true} <-
|
||||
{:scopes,
|
||||
OAuthScopesPlug.filter_descendants(["read:statuses"], oauth_token.scopes) != []} do
|
||||
true
|
||||
else
|
||||
{:restrict?, _} ->
|
||||
true
|
||||
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
@doc "Expand and authorizes a stream"
|
||||
@spec get_topic(stream :: String.t(), User.t() | nil, Token.t() | nil, Map.t()) ::
|
||||
{:ok, topic :: String.t()} | {:error, :bad_topic}
|
||||
def get_topic(stream, user, oauth_token, params \\ %{})
|
||||
|
||||
# Allow all public steams.
|
||||
def get_topic(stream, _user, _oauth_token, _params) when stream in @public_streams do
|
||||
# Allow all public steams if the instance allows unauthenticated access.
|
||||
# Otherwise, only allow users with valid oauth tokens.
|
||||
def get_topic(stream, user, oauth_token, _params) when stream in @public_streams do
|
||||
kind = if stream in @local_streams, do: :local, else: :federated
|
||||
|
||||
if can_access_stream(user, oauth_token, kind) do
|
||||
{:ok, stream}
|
||||
else
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
end
|
||||
|
||||
# Allow all hashtags streams.
|
||||
|
@ -57,12 +81,20 @@ def get_topic("hashtag", _user, _oauth_token, %{"tag" => tag} = _params) do
|
|||
end
|
||||
|
||||
# Allow remote instance streams.
|
||||
def get_topic("public:remote", _user, _oauth_token, %{"instance" => instance} = _params) do
|
||||
def get_topic("public:remote", user, oauth_token, %{"instance" => instance} = _params) do
|
||||
if can_access_stream(user, oauth_token, :federated) do
|
||||
{:ok, "public:remote:" <> instance}
|
||||
else
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
end
|
||||
|
||||
def get_topic("public:remote:media", _user, _oauth_token, %{"instance" => instance} = _params) do
|
||||
def get_topic("public:remote:media", user, oauth_token, %{"instance" => instance} = _params) do
|
||||
if can_access_stream(user, oauth_token, :federated) do
|
||||
{:ok, "public:remote:media:" <> instance}
|
||||
else
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
end
|
||||
|
||||
# Expand user streams.
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
|
|||
def project do
|
||||
[
|
||||
app: :pleroma,
|
||||
version: version("2.5.51"),
|
||||
version: version("2.5.52"),
|
||||
elixir: "~> 1.11",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
|
||||
|
|
|
@ -29,6 +29,26 @@ test "allows public" do
|
|||
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil, nil)
|
||||
end
|
||||
|
||||
test "rejects local public streams if restricted_unauthenticated is on" do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local", nil, nil)
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", nil, nil)
|
||||
end
|
||||
|
||||
test "rejects remote public streams if restricted_unauthenticated is on" do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public", nil, nil)
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:media", nil, nil)
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"})
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote:media", nil, nil, %{"instance" => "lain.com"})
|
||||
end
|
||||
|
||||
test "allows instance streams" do
|
||||
assert {:ok, "public:remote:lain.com"} =
|
||||
Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"})
|
||||
|
@ -69,6 +89,63 @@ test "allows public streams (regardless of OAuth token scopes)", %{
|
|||
end
|
||||
end
|
||||
|
||||
test "allows local public streams if restricted_unauthenticated is on", %{
|
||||
user: user,
|
||||
token: oauth_token
|
||||
} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||
|
||||
%{token: read_notifications_token} = oauth_access(["read:notifications"], user: user)
|
||||
%{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user)
|
||||
|
||||
assert {:ok, "public:local"} = Streamer.get_topic("public:local", user, oauth_token)
|
||||
|
||||
assert {:ok, "public:local:media"} =
|
||||
Streamer.get_topic("public:local:media", user, oauth_token)
|
||||
|
||||
for token <- [read_notifications_token, badly_scoped_token] do
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local", user, token)
|
||||
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", user, token)
|
||||
end
|
||||
end
|
||||
|
||||
test "allows remote public streams if restricted_unauthenticated is on", %{
|
||||
user: user,
|
||||
token: oauth_token
|
||||
} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||
|
||||
%{token: read_notifications_token} = oauth_access(["read:notifications"], user: user)
|
||||
%{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user)
|
||||
|
||||
assert {:ok, "public"} = Streamer.get_topic("public", user, oauth_token)
|
||||
assert {:ok, "public:media"} = Streamer.get_topic("public:media", user, oauth_token)
|
||||
|
||||
assert {:ok, "public:remote:lain.com"} =
|
||||
Streamer.get_topic("public:remote", user, oauth_token, %{"instance" => "lain.com"})
|
||||
|
||||
assert {:ok, "public:remote:media:lain.com"} =
|
||||
Streamer.get_topic("public:remote:media", user, oauth_token, %{
|
||||
"instance" => "lain.com"
|
||||
})
|
||||
|
||||
for token <- [read_notifications_token, badly_scoped_token] do
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public", user, token)
|
||||
assert {:error, :unauthorized} = Streamer.get_topic("public:media", user, token)
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote", user, token, %{
|
||||
"instance" => "lain.com"
|
||||
})
|
||||
|
||||
assert {:error, :unauthorized} =
|
||||
Streamer.get_topic("public:remote:media", user, token, %{
|
||||
"instance" => "lain.com"
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
test "allows user streams (with proper OAuth token scopes)", %{
|
||||
user: user,
|
||||
token: read_oauth_token
|
||||
|
|
Loading…
Reference in New Issue