Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into lazarus
This commit is contained in:
commit
a5dbf8dead
15 changed files with 118 additions and 12 deletions
|
|
@ -290,7 +290,7 @@ stop_review_app:
|
|||
amd64:
|
||||
stage: release
|
||||
image:
|
||||
name: hexpm/elixir-amd64:1.17.3-erlang-26.2.5.6-ubuntu-focal-20241011
|
||||
name: hexpm/elixir-amd64:1.17.3-erlang-27.3.4.2-ubuntu-noble-20250716
|
||||
only: &release-only
|
||||
- stable@pleroma/pleroma
|
||||
- develop@pleroma/pleroma
|
||||
|
|
@ -317,7 +317,7 @@ amd64:
|
|||
VIX_COMPILATION_MODE: PLATFORM_PROVIDED_LIBVIPS
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
before_script: &before-release
|
||||
- apt-get update && apt-get install -y cmake libmagic-dev libvips-dev erlang-dev git
|
||||
- apt-get update && apt-get install -y cmake libmagic-dev libvips-dev erlang-dev git build-essential
|
||||
- echo "import Config" > config/prod.secret.exs
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
|
|
@ -333,7 +333,7 @@ amd64-musl:
|
|||
artifacts: *release-artifacts
|
||||
only: *release-only
|
||||
image:
|
||||
name: hexpm/elixir-amd64:1.17.3-erlang-26.2.5.6-alpine-3.17.9
|
||||
name: hexpm/elixir-amd64:1.17.3-erlang-27.3.4.2-alpine-3.22.1
|
||||
tags:
|
||||
- amd64
|
||||
cache: *release-cache
|
||||
|
|
@ -377,7 +377,7 @@ arm64:
|
|||
tags:
|
||||
- arm
|
||||
image:
|
||||
name: hexpm/elixir-arm64:1.17.3-erlang-26.2.5.6-ubuntu-focal-20241011
|
||||
name: hexpm/elixir-arm64:1.17.3-erlang-27.3.4.2-ubuntu-noble-20250716
|
||||
cache: *release-cache
|
||||
variables: *release-variables
|
||||
before_script: *before-release
|
||||
|
|
@ -390,7 +390,7 @@ arm64-musl:
|
|||
tags:
|
||||
- arm
|
||||
image:
|
||||
name: hexpm/elixir-arm64:1.17.3-erlang-26.2.5.6-alpine-3.17.9
|
||||
name: hexpm/elixir-arm64:1.17.3-erlang-27.3.4.2-alpine-3.22.1
|
||||
cache: *release-cache
|
||||
variables: *release-variables
|
||||
before_script: *before-release-musl
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
# https://hub.docker.com/r/hexpm/elixir/tags
|
||||
ARG ELIXIR_IMG=hexpm/elixir
|
||||
ARG ELIXIR_VER=1.14.5
|
||||
ARG ERLANG_VER=25.3.2.14
|
||||
ARG ELIXIR_VER=1.17.3
|
||||
ARG ERLANG_VER=26.2.5.6
|
||||
ARG ALPINE_VER=3.17.9
|
||||
|
||||
FROM ${ELIXIR_IMG}:${ELIXIR_VER}-erlang-${ERLANG_VER}-alpine-${ALPINE_VER} as build
|
||||
FROM ${ELIXIR_IMG}:${ELIXIR_VER}-erlang-${ERLANG_VER}-alpine-${ALPINE_VER} AS build
|
||||
|
||||
COPY . .
|
||||
|
||||
|
|
@ -15,6 +15,7 @@ RUN apk add git gcc g++ musl-dev make cmake file-dev vips-dev &&\
|
|||
echo "import Config" > config/prod.secret.exs &&\
|
||||
mix local.hex --force &&\
|
||||
mix local.rebar --force &&\
|
||||
mix deps.clean --all &&\
|
||||
mix deps.get --only prod &&\
|
||||
mkdir release &&\
|
||||
mix release --path release
|
||||
|
|
|
|||
1
changelog.d/admin-self-revocation.security
Normal file
1
changelog.d/admin-self-revocation.security
Normal file
|
|
@ -0,0 +1 @@
|
|||
Admin API: Fixed self-revocation vulnerability where admins could accidentally revoke their own admin status via the single-user permission endpoint
|
||||
1
changelog.d/dockerfile-versions.change
Normal file
1
changelog.d/dockerfile-versions.change
Normal file
|
|
@ -0,0 +1 @@
|
|||
Update Dockerfile to use Elixir 1.17.3, Erlang 26.2.5.6, and Alpine 3.17.9 to match CI release builds
|
||||
1
changelog.d/moderation-log-unknown-actions.fix
Normal file
1
changelog.d/moderation-log-unknown-actions.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Fix ModerationLog FunctionClauseError for unknown actions
|
||||
1
changelog.d/repost-repeat-filtering-3391.add
Normal file
1
changelog.d/repost-repeat-filtering-3391.add
Normal file
|
|
@ -0,0 +1 @@
|
|||
Add only_reblogs parameter to account statuses API for filtering to show only reblogs/reposts
|
||||
|
|
@ -88,6 +88,7 @@ The `id` parameter can also be the `nickname` of the user. This only works in th
|
|||
- `only_media`: include only statuses with media attached
|
||||
- `with_muted`: include statuses/reactions from muted accounts
|
||||
- `exclude_reblogs`: exclude reblogs
|
||||
- `only_reblogs`: include only reblogs
|
||||
- `exclude_replies`: exclude replies
|
||||
- `exclude_visibilities`: exclude visibilities
|
||||
|
||||
|
|
|
|||
|
|
@ -575,6 +575,12 @@ defmodule Pleroma.ModerationLog do
|
|||
"@#{actor_nickname} requested account backup for @#{user_nickname}"
|
||||
end
|
||||
|
||||
def get_log_entry_message(%ModerationLog{data: data}) do
|
||||
actor_name = get_in(data, ["actor", "nickname"]) || "unknown"
|
||||
action = data["action"] || "unknown"
|
||||
"@#{actor_name} performed action #{action}"
|
||||
end
|
||||
|
||||
defp nicknames_to_string(nicknames) do
|
||||
nicknames
|
||||
|> Enum.map(&"@#{&1}")
|
||||
|
|
|
|||
|
|
@ -1065,6 +1065,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
from(activity in query, where: fragment("?->>'type' != 'Announce'", activity.data))
|
||||
end
|
||||
|
||||
defp restrict_reblogs(query, %{only_reblogs: true}) do
|
||||
from(activity in query, where: fragment("?->>'type' = 'Announce'", activity.data))
|
||||
end
|
||||
|
||||
defp restrict_reblogs(query, _), do: query
|
||||
|
||||
defp restrict_muted(query, %{with_muted: true}), do: query
|
||||
|
|
|
|||
|
|
@ -240,6 +240,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
render_error(conn, :not_found, "No such permission_group")
|
||||
end
|
||||
|
||||
def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
|
||||
render_error(conn, :forbidden, "You can't revoke your own admin status.")
|
||||
end
|
||||
|
||||
def right_delete(
|
||||
%{assigns: %{user: admin}} = conn,
|
||||
%{
|
||||
|
|
@ -265,10 +269,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
json(conn, fields)
|
||||
end
|
||||
|
||||
def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
|
||||
render_error(conn, :forbidden, "You can't revoke your own admin status.")
|
||||
end
|
||||
|
||||
@doc "Get a password reset token (base64 string) for given nickname"
|
||||
def get_password_reset(conn, %{"nickname" => nickname}) do
|
||||
(%User{local: true} = user) = User.get_cached_by_nickname(nickname)
|
||||
|
|
|
|||
|
|
@ -143,6 +143,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
"Include statuses from muted accounts."
|
||||
),
|
||||
Operation.parameter(:exclude_reblogs, :query, BooleanLike.schema(), "Exclude reblogs"),
|
||||
Operation.parameter(
|
||||
:only_reblogs,
|
||||
:query,
|
||||
BooleanLike.schema(),
|
||||
"Include only reblogs"
|
||||
),
|
||||
Operation.parameter(:exclude_replies, :query, BooleanLike.schema(), "Exclude replies"),
|
||||
Operation.parameter(
|
||||
:exclude_visibilities,
|
||||
|
|
|
|||
|
|
@ -308,4 +308,37 @@ defmodule Pleroma.ModerationLogTest do
|
|||
assert log.data["message"] == "@#{moderator.nickname} deleted status ##{note.id}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_log_entry_message/1" do
|
||||
setup do
|
||||
moderator = insert(:user, is_moderator: true)
|
||||
[moderator: moderator]
|
||||
end
|
||||
|
||||
test "handles unknown action types gracefully", %{moderator: moderator} do
|
||||
log_entry = %ModerationLog{
|
||||
data: %{
|
||||
"actor" => %{"nickname" => moderator.nickname},
|
||||
"action" => "unknown_action",
|
||||
"some_data" => "test_value"
|
||||
}
|
||||
}
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) =~ moderator.nickname
|
||||
assert ModerationLog.get_log_entry_message(log_entry) =~ "unknown_action"
|
||||
end
|
||||
|
||||
test "handles malformed log entries gracefully" do
|
||||
log_entry = %ModerationLog{
|
||||
data: %{
|
||||
"action" => "force_password_reset"
|
||||
# Missing "actor" and "subject" fields
|
||||
}
|
||||
}
|
||||
|
||||
message = ModerationLog.get_log_entry_message(log_entry)
|
||||
assert is_binary(message)
|
||||
assert message =~ "force_password_reset"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1270,6 +1270,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert activity == expected_activity
|
||||
end
|
||||
|
||||
test "includes only reblogs on request" do
|
||||
user = insert(:user)
|
||||
{:ok, _} = ActivityBuilder.insert(%{"type" => "Create"}, %{:user => user})
|
||||
{:ok, expected_activity} = ActivityBuilder.insert(%{"type" => "Announce"}, %{:user => user})
|
||||
|
||||
[activity] = ActivityPub.fetch_user_activities(user, nil, %{only_reblogs: true})
|
||||
|
||||
assert activity == expected_activity
|
||||
end
|
||||
|
||||
describe "irreversible filters" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -321,6 +321,36 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{user_two.nickname}"
|
||||
end
|
||||
|
||||
test "/:right DELETE, admin cannot revoke their own admin status (single)", %{
|
||||
admin: admin,
|
||||
conn: conn
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> delete("/api/pleroma/admin/users/#{admin.nickname}/permission_group/admin")
|
||||
|
||||
assert json_response(conn, 403) == %{"error" => "You can't revoke your own admin status."}
|
||||
end
|
||||
|
||||
test "/:right DELETE, admin cannot revoke their own admin status (multiple)", %{
|
||||
admin: admin,
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user, is_admin: true)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> delete("/api/pleroma/admin/users/permission_group/admin", %{
|
||||
nicknames: [admin.nickname, user.nickname]
|
||||
})
|
||||
|
||||
assert json_response(conn, 403) == %{
|
||||
"error" => "You can't revoke your own admin/moderator status."
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "/api/pleroma/admin/users/:nickname/password_reset" do
|
||||
|
|
|
|||
|
|
@ -469,6 +469,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "gets only a user's reblogs", %{user: user, conn: conn} do
|
||||
{:ok, %{id: post_id}} = CommonAPI.post(user, %{status: "HI!!!"})
|
||||
{:ok, %{id: reblog_id}} = CommonAPI.repeat(post_id, user)
|
||||
|
||||
conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?only_reblogs=true")
|
||||
assert [%{"id" => ^reblog_id}] = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?only_reblogs=1")
|
||||
assert [%{"id" => ^reblog_id}] = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "filters user's statuses by a hashtag", %{user: user, conn: conn} do
|
||||
{:ok, %{id: post_id}} = CommonAPI.post(user, %{status: "#hashtag"})
|
||||
{:ok, _post} = CommonAPI.post(user, %{status: "hashtag"})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue