forked from AkkomaGang/akkoma
list timeline filtration by params
This commit is contained in:
parent
e21af1cfe4
commit
2cb6dc5a3a
4 changed files with 145 additions and 76 deletions
|
@ -25,7 +25,7 @@ def home_operation do
|
||||||
security: [%{"oAuth" => ["read:statuses"]}],
|
security: [%{"oAuth" => ["read:statuses"]}],
|
||||||
parameters: [
|
parameters: [
|
||||||
local_param(),
|
local_param(),
|
||||||
remote_param(),
|
only_remote_param(),
|
||||||
only_media_param(),
|
only_media_param(),
|
||||||
with_muted_param(),
|
with_muted_param(),
|
||||||
exclude_visibilities_param(),
|
exclude_visibilities_param(),
|
||||||
|
@ -134,6 +134,9 @@ def list_operation do
|
||||||
required: true
|
required: true
|
||||||
),
|
),
|
||||||
with_muted_param(),
|
with_muted_param(),
|
||||||
|
local_param(),
|
||||||
|
only_remote_param(),
|
||||||
|
only_media_param(),
|
||||||
exclude_visibilities_param() | pagination_params()
|
exclude_visibilities_param() | pagination_params()
|
||||||
],
|
],
|
||||||
operationId: "TimelineController.list",
|
operationId: "TimelineController.list",
|
||||||
|
@ -201,7 +204,7 @@ defp only_media_param do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp remote_param do
|
defp only_remote_param do
|
||||||
Operation.parameter(
|
Operation.parameter(
|
||||||
:only_remote,
|
:only_remote,
|
||||||
:query,
|
:query,
|
||||||
|
|
|
@ -192,6 +192,7 @@ def list(%{assigns: %{user: user}} = conn, %{list_id: id} = params) do
|
||||||
|> Map.put(:blocking_user, user)
|
|> Map.put(:blocking_user, user)
|
||||||
|> Map.put(:user, user)
|
|> Map.put(:user, user)
|
||||||
|> Map.put(:muting_user, user)
|
|> Map.put(:muting_user, user)
|
||||||
|
|> Map.put(:local_only, params[:local])
|
||||||
|
|
||||||
# we must filter the following list for the user to avoid leaking statuses the user
|
# we must filter the following list for the user to avoid leaking statuses the user
|
||||||
# does not actually have permission to see (for more info, peruse security issue #270).
|
# does not actually have permission to see (for more info, peruse security issue #270).
|
||||||
|
|
|
@ -92,42 +92,13 @@ test "muted emotions", %{user: user, conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "local/remote filtering", %{conn: conn, user: user} do
|
test "local/remote filtering", %{conn: conn, user: user} do
|
||||||
local = insert(:user)
|
local_user = insert(:user)
|
||||||
remote = insert(:user, local: false)
|
{:ok, user, local_user} = User.follow(user, local_user)
|
||||||
|
{:ok, local_activity} = CommonAPI.post(local_user, %{status: "Status"})
|
||||||
|
|
||||||
{:ok, user, local} = User.follow(user, local)
|
remote_user = insert(:user, local: false)
|
||||||
{:ok, _user, remote} = User.follow(user, remote)
|
{:ok, _user, remote_user} = User.follow(user, remote_user)
|
||||||
|
remote_activity = create_remote_activity(remote_user)
|
||||||
object1 =
|
|
||||||
insert(:note, %{
|
|
||||||
data: %{
|
|
||||||
"to" => ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(local)]
|
|
||||||
},
|
|
||||||
user: local
|
|
||||||
})
|
|
||||||
|
|
||||||
activity1 =
|
|
||||||
insert(:note_activity, %{
|
|
||||||
note: object1,
|
|
||||||
recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(local)],
|
|
||||||
user: local
|
|
||||||
})
|
|
||||||
|
|
||||||
object2 =
|
|
||||||
insert(:note, %{
|
|
||||||
data: %{
|
|
||||||
"to" => ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(remote)]
|
|
||||||
},
|
|
||||||
user: remote
|
|
||||||
})
|
|
||||||
|
|
||||||
activity2 =
|
|
||||||
insert(:note_activity, %{
|
|
||||||
note: object2,
|
|
||||||
recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(remote)],
|
|
||||||
user: remote,
|
|
||||||
local: false
|
|
||||||
})
|
|
||||||
|
|
||||||
resp1 =
|
resp1 =
|
||||||
conn
|
conn
|
||||||
|
@ -136,8 +107,8 @@ test "local/remote filtering", %{conn: conn, user: user} do
|
||||||
|
|
||||||
without_filter_ids = Enum.map(resp1, & &1["id"])
|
without_filter_ids = Enum.map(resp1, & &1["id"])
|
||||||
|
|
||||||
assert activity1.id in without_filter_ids
|
assert local_activity.id in without_filter_ids
|
||||||
assert activity2.id in without_filter_ids
|
assert remote_activity.id in without_filter_ids
|
||||||
|
|
||||||
resp2 =
|
resp2 =
|
||||||
conn
|
conn
|
||||||
|
@ -146,8 +117,8 @@ test "local/remote filtering", %{conn: conn, user: user} do
|
||||||
|
|
||||||
only_local_ids = Enum.map(resp2, & &1["id"])
|
only_local_ids = Enum.map(resp2, & &1["id"])
|
||||||
|
|
||||||
assert activity1.id in only_local_ids
|
assert local_activity.id in only_local_ids
|
||||||
refute activity2.id in only_local_ids
|
refute remote_activity.id in only_local_ids
|
||||||
|
|
||||||
resp3 =
|
resp3 =
|
||||||
conn
|
conn
|
||||||
|
@ -156,8 +127,8 @@ test "local/remote filtering", %{conn: conn, user: user} do
|
||||||
|
|
||||||
only_remote_ids = Enum.map(resp3, & &1["id"])
|
only_remote_ids = Enum.map(resp3, & &1["id"])
|
||||||
|
|
||||||
refute activity1.id in only_remote_ids
|
refute local_activity.id in only_remote_ids
|
||||||
assert activity2.id in only_remote_ids
|
assert remote_activity.id in only_remote_ids
|
||||||
|
|
||||||
resp4 =
|
resp4 =
|
||||||
conn
|
conn
|
||||||
|
@ -171,40 +142,9 @@ test "only_media flag", %{conn: conn, user: user} do
|
||||||
other = insert(:user)
|
other = insert(:user)
|
||||||
{:ok, _, other} = User.follow(user, other)
|
{:ok, _, other} = User.follow(user, other)
|
||||||
|
|
||||||
without_media =
|
{:ok, without_media} = CommonAPI.post(other, %{status: "some status"})
|
||||||
insert(:note_activity,
|
|
||||||
user: other,
|
|
||||||
recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(other)]
|
|
||||||
)
|
|
||||||
|
|
||||||
obj =
|
with_media = create_with_media_activity(other)
|
||||||
insert(:note, %{
|
|
||||||
data: %{
|
|
||||||
"attachment" => [
|
|
||||||
%{
|
|
||||||
"mediaType" => "image/jpeg",
|
|
||||||
"name" => "an_image.jpg",
|
|
||||||
"type" => "Document",
|
|
||||||
"url" => [
|
|
||||||
%{
|
|
||||||
"href" =>
|
|
||||||
"http://localhost:4001/media/8270697e-104f-4a54-a7c1-514bb6713f2c/some_image.jpg",
|
|
||||||
"mediaType" => "image/jpeg",
|
|
||||||
"type" => "Link"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
user: other
|
|
||||||
})
|
|
||||||
|
|
||||||
with_media =
|
|
||||||
insert(:note_activity, %{
|
|
||||||
note: obj,
|
|
||||||
recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(other)],
|
|
||||||
user: other
|
|
||||||
})
|
|
||||||
|
|
||||||
resp1 =
|
resp1 =
|
||||||
conn
|
conn
|
||||||
|
@ -680,6 +620,67 @@ test "muted emotions", %{user: user, conn: conn} do
|
||||||
}
|
}
|
||||||
] = result
|
] = result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "filering with params", %{user: user, conn: conn} do
|
||||||
|
{:ok, list} = Pleroma.List.create("name", user)
|
||||||
|
|
||||||
|
local_user = insert(:user)
|
||||||
|
{:ok, local_activity} = CommonAPI.post(local_user, %{status: "Marisa is stupid."})
|
||||||
|
with_media = create_with_media_activity(local_user)
|
||||||
|
{:ok, list} = Pleroma.List.follow(list, local_user)
|
||||||
|
|
||||||
|
remote_user = insert(:user, local: false)
|
||||||
|
remote_activity = create_remote_activity(remote_user)
|
||||||
|
{:ok, list} = Pleroma.List.follow(list, remote_user)
|
||||||
|
|
||||||
|
resp1 =
|
||||||
|
conn |> get("/api/v1/timelines/list/#{list.id}") |> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
all_ids = Enum.map(resp1, & &1["id"])
|
||||||
|
|
||||||
|
assert local_activity.id in all_ids
|
||||||
|
assert with_media.id in all_ids
|
||||||
|
assert remote_activity.id in all_ids
|
||||||
|
|
||||||
|
resp2 =
|
||||||
|
conn
|
||||||
|
|> get("/api/v1/timelines/list/#{list.id}?local=true")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
only_local_ids = Enum.map(resp2, & &1["id"])
|
||||||
|
|
||||||
|
assert local_activity.id in only_local_ids
|
||||||
|
assert with_media.id in only_local_ids
|
||||||
|
refute remote_activity.id in only_local_ids
|
||||||
|
|
||||||
|
resp3 =
|
||||||
|
conn
|
||||||
|
|> get("/api/v1/timelines/list/#{list.id}?only_remote=true")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
only_remote_ids = Enum.map(resp3, & &1["id"])
|
||||||
|
|
||||||
|
refute local_activity.id in only_remote_ids
|
||||||
|
refute with_media.id in only_remote_ids
|
||||||
|
assert remote_activity.id in only_remote_ids
|
||||||
|
|
||||||
|
resp4 =
|
||||||
|
conn
|
||||||
|
|> get("/api/v1/timelines/list/#{list.id}?only_media=true")
|
||||||
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
|
only_media_ids = Enum.map(resp4, & &1["id"])
|
||||||
|
|
||||||
|
refute local_activity.id in only_media_ids
|
||||||
|
assert with_media.id in only_media_ids
|
||||||
|
refute remote_activity.id in only_media_ids
|
||||||
|
|
||||||
|
assert conn
|
||||||
|
|> get(
|
||||||
|
"/api/v1/timelines/list/#{list.id}?only_media=true&local=true&only_remote=true"
|
||||||
|
)
|
||||||
|
|> json_response_and_validate_schema(200) == []
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "hashtag" do
|
describe "hashtag" do
|
||||||
|
@ -862,4 +863,37 @@ test "with `%{local: true, federated: false}`, forbids unauthenticated access to
|
||||||
ensure_authenticated_access(base_uri)
|
ensure_authenticated_access(base_uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp create_remote_activity(user) do
|
||||||
|
obj =
|
||||||
|
insert(:note, %{
|
||||||
|
data: %{
|
||||||
|
"to" => [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
User.ap_followers(user)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
user: user
|
||||||
|
})
|
||||||
|
|
||||||
|
insert(:note_activity, %{
|
||||||
|
note: obj,
|
||||||
|
recipients: [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
User.ap_followers(user)
|
||||||
|
],
|
||||||
|
user: user,
|
||||||
|
local: false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp create_with_media_activity(user) do
|
||||||
|
obj = insert(:attachment_note, user: user)
|
||||||
|
|
||||||
|
insert(:note_activity, %{
|
||||||
|
note: obj,
|
||||||
|
recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(user)],
|
||||||
|
user: user
|
||||||
|
})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -104,6 +104,37 @@ def note_factory(attrs \\ %{}) do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def attachment_note_factory(attrs \\ %{}) do
|
||||||
|
user = attrs[:user] || insert(:user)
|
||||||
|
{length, attrs} = Map.pop(attrs, :length, 1)
|
||||||
|
|
||||||
|
data = %{
|
||||||
|
"attachment" =>
|
||||||
|
Stream.repeatedly(fn -> attachment_data(user.ap_id, attrs[:href]) end)
|
||||||
|
|> Enum.take(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
build(:note, Map.put(attrs, :data, data))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp attachment_data(ap_id, href) do
|
||||||
|
href = href || sequence(:href, &"#{Pleroma.Web.Endpoint.url()}/media/#{&1}.jpg")
|
||||||
|
|
||||||
|
%{
|
||||||
|
"url" => [
|
||||||
|
%{
|
||||||
|
"href" => href,
|
||||||
|
"type" => "Link",
|
||||||
|
"mediaType" => "image/jpeg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name" => "some name",
|
||||||
|
"type" => "Document",
|
||||||
|
"actor" => ap_id,
|
||||||
|
"mediaType" => "image/jpeg"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def audio_factory(attrs \\ %{}) do
|
def audio_factory(attrs \\ %{}) do
|
||||||
text = sequence(:text, &"lain radio episode #{&1}")
|
text = sequence(:text, &"lain radio episode #{&1}")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue