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
|
### Removed
|
||||||
- BREAKING: Support for passwords generated with `crypt(3)` (Gnu Social migration artifact)
|
- 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
|
## 2.5.1
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -25,6 +25,7 @@ defmodule Pleroma.Web.Streamer do
|
||||||
def registry, do: @registry
|
def registry, do: @registry
|
||||||
|
|
||||||
@public_streams ["public", "public:local", "public:media", "public:local:media"]
|
@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"]
|
@user_streams ["user", "user:notification", "direct", "user:pleroma_chat"]
|
||||||
|
|
||||||
@doc "Expands and authorizes a stream, and registers the process for streaming."
|
@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
|
||||||
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"
|
@doc "Expand and authorizes a stream"
|
||||||
@spec get_topic(stream :: String.t(), User.t() | nil, Token.t() | nil, Map.t()) ::
|
@spec get_topic(stream :: String.t(), User.t() | nil, Token.t() | nil, Map.t()) ::
|
||||||
{:ok, topic :: String.t()} | {:error, :bad_topic}
|
{:ok, topic :: String.t()} | {:error, :bad_topic}
|
||||||
def get_topic(stream, user, oauth_token, params \\ %{})
|
def get_topic(stream, user, oauth_token, params \\ %{})
|
||||||
|
|
||||||
# Allow all public steams.
|
# Allow all public steams if the instance allows unauthenticated access.
|
||||||
def get_topic(stream, _user, _oauth_token, _params) when stream in @public_streams do
|
# 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}
|
{:ok, stream}
|
||||||
|
else
|
||||||
|
{:error, :unauthorized}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Allow all hashtags streams.
|
# Allow all hashtags streams.
|
||||||
|
@ -57,12 +81,20 @@ def get_topic("hashtag", _user, _oauth_token, %{"tag" => tag} = _params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Allow remote instance streams.
|
# 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}
|
{:ok, "public:remote:" <> instance}
|
||||||
|
else
|
||||||
|
{:error, :unauthorized}
|
||||||
|
end
|
||||||
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}
|
{:ok, "public:remote:media:" <> instance}
|
||||||
|
else
|
||||||
|
{:error, :unauthorized}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Expand user streams.
|
# Expand user streams.
|
||||||
|
|
2
mix.exs
2
mix.exs
|
@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
|
||||||
def project do
|
def project do
|
||||||
[
|
[
|
||||||
app: :pleroma,
|
app: :pleroma,
|
||||||
version: version("2.5.51"),
|
version: version("2.5.52"),
|
||||||
elixir: "~> 1.11",
|
elixir: "~> 1.11",
|
||||||
elixirc_paths: elixirc_paths(Mix.env()),
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
|
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)
|
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil, nil)
|
||||||
end
|
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
|
test "allows instance streams" do
|
||||||
assert {:ok, "public:remote:lain.com"} =
|
assert {:ok, "public:remote:lain.com"} =
|
||||||
Streamer.get_topic("public:remote", nil, nil, %{"instance" => "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
|
||||||
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)", %{
|
test "allows user streams (with proper OAuth token scopes)", %{
|
||||||
user: user,
|
user: user,
|
||||||
token: read_oauth_token
|
token: read_oauth_token
|
||||||
|
|
Loading…
Reference in New Issue