Merge remote-tracking branch 'remotes/origin/develop' into clear-config-test-improvements
# Conflicts: # test/web/mastodon_api/controllers/account_controller_test.exs
This commit is contained in:
commit
0e27c274f4
|
@ -62,19 +62,21 @@ unit-testing:
|
||||||
- mix ecto.migrate
|
- mix ecto.migrate
|
||||||
- mix coveralls --preload-modules
|
- mix coveralls --preload-modules
|
||||||
|
|
||||||
federated-testing:
|
# Removed to fix CI issue. In this early state it wasn't adding much value anyway.
|
||||||
stage: test
|
# TODO Fix and reinstate federated testing
|
||||||
cache: *testing_cache_policy
|
# federated-testing:
|
||||||
services:
|
# stage: test
|
||||||
- name: minibikini/postgres-with-rum:12
|
# cache: *testing_cache_policy
|
||||||
alias: postgres
|
# services:
|
||||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
# - name: minibikini/postgres-with-rum:12
|
||||||
script:
|
# alias: postgres
|
||||||
- mix deps.get
|
# command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||||
- mix ecto.create
|
# script:
|
||||||
- mix ecto.migrate
|
# - mix deps.get
|
||||||
- epmd -daemon
|
# - mix ecto.create
|
||||||
- mix test --trace --only federated
|
# - mix ecto.migrate
|
||||||
|
# - epmd -daemon
|
||||||
|
# - mix test --trace --only federated
|
||||||
|
|
||||||
unit-testing-rum:
|
unit-testing-rum:
|
||||||
stage: test
|
stage: test
|
||||||
|
|
|
@ -10,6 +10,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
### Removed
|
### Removed
|
||||||
- **Breaking:** removed `with_move` parameter from notifications timeline.
|
- **Breaking:** removed `with_move` parameter from notifications timeline.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
|
||||||
|
- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
|
||||||
|
<details>
|
||||||
|
<summary>API Changes</summary>
|
||||||
|
- Mastodon API: Support for `include_types` in `/api/v1/notifications`.
|
||||||
|
</details>
|
||||||
|
|
||||||
## [2.0.0] - 2019-03-08
|
## [2.0.0] - 2019-03-08
|
||||||
### Security
|
### Security
|
||||||
- Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request.
|
- Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request.
|
||||||
|
|
|
@ -624,6 +624,11 @@
|
||||||
parameters: [gin_fuzzy_search_limit: "500"],
|
parameters: [gin_fuzzy_search_limit: "500"],
|
||||||
prepare: :unnamed
|
prepare: :unnamed
|
||||||
|
|
||||||
|
config :pleroma, :restrict_unauthenticated,
|
||||||
|
timelines: %{local: false, federated: false},
|
||||||
|
profiles: %{local: false, remote: false},
|
||||||
|
activities: %{local: false, remote: false}
|
||||||
|
|
||||||
# Import environment specific config. This must remain at the bottom
|
# Import environment specific config. This must remain at the bottom
|
||||||
# of this file so it overrides the configuration defined above.
|
# of this file so it overrides the configuration defined above.
|
||||||
import_config "#{Mix.env()}.exs"
|
import_config "#{Mix.env()}.exs"
|
||||||
|
|
|
@ -2915,5 +2915,65 @@
|
||||||
suggestions: [2]
|
suggestions: [2]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
group: :pleroma,
|
||||||
|
key: :restrict_unauthenticated,
|
||||||
|
type: :group,
|
||||||
|
description:
|
||||||
|
"Disallow viewing timelines, user profiles and statuses for unauthenticated users.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :timelines,
|
||||||
|
type: :map,
|
||||||
|
description: "Settings for public and federated timelines.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :local,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view public timeline."
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :federated,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view federated timeline."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :profiles,
|
||||||
|
type: :map,
|
||||||
|
description: "Settings for user profiles.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :local,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view local user profiles."
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :remote,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view remote user profiles."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :activities,
|
||||||
|
type: :map,
|
||||||
|
description: "Settings for statuses.",
|
||||||
|
children: [
|
||||||
|
%{
|
||||||
|
key: :local,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view local statuses."
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :remote,
|
||||||
|
type: :boolean,
|
||||||
|
description: "Disallow view remote statuses."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -117,6 +117,7 @@ The `type` value is `pleroma:emoji_reaction`. Has these fields:
|
||||||
Accepts additional parameters:
|
Accepts additional parameters:
|
||||||
|
|
||||||
- `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`.
|
- `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`.
|
||||||
|
- `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`.
|
||||||
|
|
||||||
## POST `/api/v1/statuses`
|
## POST `/api/v1/statuses`
|
||||||
|
|
||||||
|
|
|
@ -872,3 +872,21 @@ config :auto_linker,
|
||||||
## :configurable_from_database
|
## :configurable_from_database
|
||||||
|
|
||||||
Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
|
Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Restrict entities access for unauthenticated users
|
||||||
|
|
||||||
|
### :restrict_unauthenticated
|
||||||
|
|
||||||
|
Restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
|
||||||
|
|
||||||
|
* `timelines` - public and federated timelines
|
||||||
|
* `local` - public timeline
|
||||||
|
* `federated`
|
||||||
|
* `profiles` - user profiles
|
||||||
|
* `local`
|
||||||
|
* `remote`
|
||||||
|
* `activities` - statuses
|
||||||
|
* `local`
|
||||||
|
* `remote`
|
|
@ -237,7 +237,18 @@ def visible_for?(user, for_user \\ nil)
|
||||||
|
|
||||||
def visible_for?(%User{invisible: true}, _), do: false
|
def visible_for?(%User{invisible: true}, _), do: false
|
||||||
|
|
||||||
def visible_for?(%User{id: user_id}, %User{id: for_id}) when user_id == for_id, do: true
|
def visible_for?(%User{id: user_id}, %User{id: user_id}), do: true
|
||||||
|
|
||||||
|
def visible_for?(%User{local: local} = user, nil) do
|
||||||
|
cfg_key =
|
||||||
|
if local,
|
||||||
|
do: :local,
|
||||||
|
else: :remote
|
||||||
|
|
||||||
|
if Config.get([:restrict_unauthenticated, :profiles, cfg_key]),
|
||||||
|
do: false,
|
||||||
|
else: account_status(user) == :active
|
||||||
|
end
|
||||||
|
|
||||||
def visible_for?(%User{} = user, for_user) do
|
def visible_for?(%User{} = user, for_user) do
|
||||||
account_status(user) == :active || superuser?(for_user)
|
account_status(user) == :active || superuser?(for_user)
|
||||||
|
|
|
@ -44,6 +44,7 @@ def is_direct?(activity) do
|
||||||
def is_list?(%{data: %{"listMessage" => _}}), do: true
|
def is_list?(%{data: %{"listMessage" => _}}), do: true
|
||||||
def is_list?(_), do: false
|
def is_list?(_), do: false
|
||||||
|
|
||||||
|
@spec visible_for_user?(Activity.t(), User.t() | nil) :: boolean()
|
||||||
def visible_for_user?(%{actor: ap_id}, %User{ap_id: ap_id}), do: true
|
def visible_for_user?(%{actor: ap_id}, %User{ap_id: ap_id}), do: true
|
||||||
|
|
||||||
def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{} = user) do
|
def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{} = user) do
|
||||||
|
@ -55,14 +56,21 @@ def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{
|
||||||
|
|
||||||
def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false
|
def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false
|
||||||
|
|
||||||
def visible_for_user?(activity, nil) do
|
def visible_for_user?(%{local: local} = activity, nil) do
|
||||||
is_public?(activity)
|
cfg_key =
|
||||||
|
if local,
|
||||||
|
do: :local,
|
||||||
|
else: :remote
|
||||||
|
|
||||||
|
if Pleroma.Config.get([:restrict_unauthenticated, :activities, cfg_key]),
|
||||||
|
do: false,
|
||||||
|
else: is_public?(activity)
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible_for_user?(activity, user) do
|
def visible_for_user?(activity, user) do
|
||||||
x = [user.ap_id | User.following(user)]
|
x = [user.ap_id | User.following(user)]
|
||||||
y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || [])
|
y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || [])
|
||||||
visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y))
|
is_public?(activity) || Enum.any?(x, &(&1 in y))
|
||||||
end
|
end
|
||||||
|
|
||||||
def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do
|
def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do
|
||||||
|
|
|
@ -60,7 +60,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||||
when action != :create
|
when action not in [:create, :show, :statuses]
|
||||||
)
|
)
|
||||||
|
|
||||||
@relations [:follow, :unfollow]
|
@relations [:follow, :unfollow]
|
||||||
|
@ -259,7 +259,8 @@ def show(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
|
||||||
|
|
||||||
@doc "GET /api/v1/accounts/:id/statuses"
|
@doc "GET /api/v1/accounts/:id/statuses"
|
||||||
def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
||||||
with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user) do
|
with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user),
|
||||||
|
true <- User.visible_for?(user, reading_user) do
|
||||||
params =
|
params =
|
||||||
params
|
params
|
||||||
|> Map.put("tag", params["tagged"])
|
|> Map.put("tag", params["tagged"])
|
||||||
|
@ -271,6 +272,8 @@ def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
||||||
|> add_link_headers(activities)
|
|> add_link_headers(activities)
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> render("index.json", activities: activities, for: reading_user, as: :activity)
|
|> render("index.json", activities: activities, for: reading_user, as: :activity)
|
||||||
|
else
|
||||||
|
_e -> render_error(conn, :not_found, "Can't find user")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||||
%{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark]
|
%{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
|
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action not in [:index, :show])
|
||||||
|
|
||||||
@rate_limited_status_actions ~w(reblog unreblog favourite unfavourite create delete)a
|
@rate_limited_status_actions ~w(reblog unreblog favourite unfavourite create delete)a
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
|
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
|
||||||
plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)
|
plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)
|
||||||
|
|
||||||
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
|
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action != :public)
|
||||||
|
|
||||||
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
|
plug(:put_view, Pleroma.Web.MastodonAPI.StatusView)
|
||||||
|
|
||||||
|
@ -75,17 +75,30 @@ def direct(%{assigns: %{user: user}} = conn, params) do
|
||||||
def public(%{assigns: %{user: user}} = conn, params) do
|
def public(%{assigns: %{user: user}} = conn, params) do
|
||||||
local_only = truthy_param?(params["local"])
|
local_only = truthy_param?(params["local"])
|
||||||
|
|
||||||
activities =
|
cfg_key =
|
||||||
params
|
if local_only do
|
||||||
|> Map.put("type", ["Create", "Announce"])
|
:local
|
||||||
|> Map.put("local_only", local_only)
|
else
|
||||||
|> Map.put("blocking_user", user)
|
:federated
|
||||||
|> Map.put("muting_user", user)
|
end
|
||||||
|> ActivityPub.fetch_public_activities()
|
|
||||||
|
|
||||||
conn
|
restrict? = Pleroma.Config.get([:restrict_unauthenticated, :timelines, cfg_key])
|
||||||
|> add_link_headers(activities, %{"local" => local_only})
|
|
||||||
|> render("index.json", activities: activities, for: user, as: :activity)
|
if not (restrict? and is_nil(user)) do
|
||||||
|
activities =
|
||||||
|
params
|
||||||
|
|> Map.put("type", ["Create", "Announce"])
|
||||||
|
|> Map.put("local_only", local_only)
|
||||||
|
|> Map.put("blocking_user", user)
|
||||||
|
|> Map.put("muting_user", user)
|
||||||
|
|> ActivityPub.fetch_public_activities()
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> add_link_headers(activities, %{"local" => local_only})
|
||||||
|
|> render("index.json", activities: activities, for: user, as: :activity)
|
||||||
|
else
|
||||||
|
render_error(conn, :unauthorized, "authorization required for timeline view")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def hashtag_fetching(params, user, local_only) do
|
def hashtag_fetching(params, user, local_only) do
|
||||||
|
|
|
@ -55,6 +55,7 @@ def get_notifications(user, params \\ %{}) do
|
||||||
|
|
||||||
user
|
user
|
||||||
|> Notification.for_user_query(options)
|
|> Notification.for_user_query(options)
|
||||||
|
|> restrict(:include_types, options)
|
||||||
|> restrict(:exclude_types, options)
|
|> restrict(:exclude_types, options)
|
||||||
|> restrict(:account_ap_id, options)
|
|> restrict(:account_ap_id, options)
|
||||||
|> Pagination.fetch_paginated(params)
|
|> Pagination.fetch_paginated(params)
|
||||||
|
@ -69,6 +70,7 @@ def get_scheduled_activities(user, params \\ %{}) do
|
||||||
defp cast_params(params) do
|
defp cast_params(params) do
|
||||||
param_types = %{
|
param_types = %{
|
||||||
exclude_types: {:array, :string},
|
exclude_types: {:array, :string},
|
||||||
|
include_types: {:array, :string},
|
||||||
exclude_visibilities: {:array, :string},
|
exclude_visibilities: {:array, :string},
|
||||||
reblogs: :boolean,
|
reblogs: :boolean,
|
||||||
with_muted: :boolean,
|
with_muted: :boolean,
|
||||||
|
@ -79,14 +81,16 @@ defp cast_params(params) do
|
||||||
changeset.changes
|
changeset.changes
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
|
defp restrict(query, :include_types, %{include_types: mastodon_types = [_ | _]}) do
|
||||||
ap_types =
|
ap_types = convert_and_filter_mastodon_types(mastodon_types)
|
||||||
mastodon_types
|
|
||||||
|> Enum.map(&Activity.from_mastodon_notification_type/1)
|
|
||||||
|> Enum.filter(& &1)
|
|
||||||
|
|
||||||
query
|
where(query, [q, a], fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
||||||
|> where([q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
end
|
||||||
|
|
||||||
|
defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
|
||||||
|
ap_types = convert_and_filter_mastodon_types(mastodon_types)
|
||||||
|
|
||||||
|
where(query, [q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
||||||
|
@ -94,4 +98,10 @@ defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict(query, _, _), do: query
|
defp restrict(query, _, _), do: query
|
||||||
|
|
||||||
|
defp convert_and_filter_mastodon_types(types) do
|
||||||
|
types
|
||||||
|
|> Enum.map(&Activity.from_mastodon_notification_type/1)
|
||||||
|
|> Enum.filter(& &1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,6 +60,7 @@ def raw_nodeinfo do
|
||||||
"pleroma_explicit_addressing",
|
"pleroma_explicit_addressing",
|
||||||
"shareable_emoji_packs",
|
"shareable_emoji_packs",
|
||||||
"multifetch",
|
"multifetch",
|
||||||
|
"pleroma:api/v1/notifications:include_types_filter",
|
||||||
if Config.get([:media_proxy, :enabled]) do
|
if Config.get([:media_proxy, :enabled]) do
|
||||||
"media_proxy"
|
"media_proxy"
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
|
|
||||||
|
alias Pleroma.Config
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
@ -46,7 +47,7 @@ test "works by nickname" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "works by nickname for remote users" do
|
test "works by nickname for remote users" do
|
||||||
Pleroma.Config.put([:instance, :limit_to_local_content], false)
|
Config.put([:instance, :limit_to_local_content], false)
|
||||||
user = insert(:user, nickname: "user@example.com", local: false)
|
user = insert(:user, nickname: "user@example.com", local: false)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -58,7 +59,7 @@ test "works by nickname for remote users" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "respects limit_to_local_content == :all for remote user nicknames" do
|
test "respects limit_to_local_content == :all for remote user nicknames" do
|
||||||
Pleroma.Config.put([:instance, :limit_to_local_content], :all)
|
Config.put([:instance, :limit_to_local_content], :all)
|
||||||
|
|
||||||
user = insert(:user, nickname: "user@example.com", local: false)
|
user = insert(:user, nickname: "user@example.com", local: false)
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ test "respects limit_to_local_content == :all for remote user nicknames" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
|
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
|
||||||
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
|
Config.put([:instance, :limit_to_local_content], :unauthenticated)
|
||||||
|
|
||||||
user = insert(:user, nickname: "user@example.com", local: false)
|
user = insert(:user, nickname: "user@example.com", local: false)
|
||||||
reading_user = insert(:user)
|
reading_user = insert(:user)
|
||||||
|
@ -140,6 +141,106 @@ test "returns 404 for internal.fetch actor", %{conn: conn} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_users do
|
||||||
|
local = insert(:user)
|
||||||
|
remote = insert(:user, local: false)
|
||||||
|
{:ok, local: local, remote: remote}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "user fetching with restrict unauthenticated profiles for local and remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "user fetching with restrict unauthenticated profiles for local" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "user fetching with restrict unauthenticated profiles for remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "user timelines" do
|
describe "user timelines" do
|
||||||
setup do: oauth_access(["read:statuses"])
|
setup do: oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
@ -293,6 +394,110 @@ test "the user views their own timelines and excludes direct messages", %{
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_activities(%{local: local, remote: remote}) do
|
||||||
|
insert(:note_activity, user: local)
|
||||||
|
insert(:note_activity, user: remote, local: false)
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "statuses with restrict unauthenticated profiles for local and remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
setup :local_and_remote_activities
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "statuses with restrict unauthenticated profiles for local" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
setup :local_and_remote_activities
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "statuses with restrict unauthenticated profiles for remote" do
|
||||||
|
setup do: local_and_remote_users()
|
||||||
|
setup :local_and_remote_activities
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :profiles, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :profiles, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Can't find user"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "followers" do
|
describe "followers" do
|
||||||
setup do: oauth_access(["read:accounts"])
|
setup do: oauth_access(["read:accounts"])
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,51 @@ test "filters notifications using exclude_types" do
|
||||||
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "filters notifications using include_types" do
|
||||||
|
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"})
|
||||||
|
{:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
|
||||||
|
{:ok, favorite_activity, _} = CommonAPI.favorite(create_activity.id, other_user)
|
||||||
|
{:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user)
|
||||||
|
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
|
||||||
|
|
||||||
|
mention_notification_id = get_notification_id_by_activity(mention_activity)
|
||||||
|
favorite_notification_id = get_notification_id_by_activity(favorite_activity)
|
||||||
|
reblog_notification_id = get_notification_id_by_activity(reblog_activity)
|
||||||
|
follow_notification_id = get_notification_id_by_activity(follow_activity)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["follow"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^follow_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["mention"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^mention_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["favourite"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^favorite_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
conn_res = get(conn, "/api/v1/notifications", %{include_types: ["reblog"]})
|
||||||
|
|
||||||
|
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
|
||||||
|
|
||||||
|
result = conn |> get("/api/v1/notifications") |> json_response(200)
|
||||||
|
|
||||||
|
assert length(result) == 4
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get("/api/v1/notifications", %{
|
||||||
|
include_types: ["follow", "mention", "favourite", "reblog"]
|
||||||
|
})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert length(result) == 4
|
||||||
|
end
|
||||||
|
|
||||||
test "destroy multiple" do
|
test "destroy multiple" do
|
||||||
%{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
|
%{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
|
@ -476,6 +476,103 @@ test "get a status" do
|
||||||
assert id == to_string(activity.id)
|
assert id == to_string(activity.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_activities do
|
||||||
|
local = insert(:note_activity)
|
||||||
|
remote = insert(:note_activity, local: false)
|
||||||
|
{:ok, local: local, remote: remote}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "status with restrict unauthenticated activities for local and remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "status with restrict unauthenticated activities for local" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "status with restrict unauthenticated activities for remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
|
||||||
|
assert json_response(res_conn, :not_found) == %{
|
||||||
|
"error" => "Record not found"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
|
||||||
|
assert %{"id" => _} = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "getting a status that doesn't exist returns 404" do
|
test "getting a status that doesn't exist returns 404" do
|
||||||
%{conn: conn} = oauth_access(["read:statuses"])
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
|
@ -514,6 +611,78 @@ test "get statuses by IDs" do
|
||||||
assert [%{"id" => ^id1}, %{"id" => ^id2}] = Enum.sort_by(json_response(conn, :ok), & &1["id"])
|
assert [%{"id" => ^id1}, %{"id" => ^id2}] = Enum.sort_by(json_response(conn, :ok), & &1["id"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "getting statuses by ids with restricted unauthenticated for local and remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert json_response(res_conn, 200) == []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "getting statuses by ids with restricted unauthenticated for local" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
remote_id = remote.id
|
||||||
|
assert [%{"id" => ^remote_id}] = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "getting statuses by ids with restricted unauthenticated for remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :activities, :remote]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :activities, :remote], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
local_id = local.id
|
||||||
|
assert [%{"id" => ^local_id}] = json_response(res_conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{local: local, remote: remote} do
|
||||||
|
%{conn: conn} = oauth_access(["read"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]})
|
||||||
|
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "deleting a status" do
|
describe "deleting a status" do
|
||||||
test "when you created it" do
|
test "when you created it" do
|
||||||
%{user: author, conn: conn} = oauth_access(["write:statuses"])
|
%{user: author, conn: conn} = oauth_access(["write:statuses"])
|
||||||
|
|
|
@ -12,8 +12,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
clear_config([:instance, :public])
|
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
:ok
|
:ok
|
||||||
|
@ -80,15 +78,6 @@ test "the public timeline", %{conn: conn} do
|
||||||
assert [%{"content" => "test"}] = json_response(conn, :ok)
|
assert [%{"content" => "test"}] = json_response(conn, :ok)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "the public timeline when public is set to false", %{conn: conn} do
|
|
||||||
Config.put([:instance, :public], false)
|
|
||||||
|
|
||||||
assert %{"error" => "This resource requires authentication."} ==
|
|
||||||
conn
|
|
||||||
|> get("/api/v1/timelines/public", %{"local" => "False"})
|
|
||||||
|> json_response(:forbidden)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "the public timeline includes only public statuses for an authenticated user" do
|
test "the public timeline includes only public statuses for an authenticated user" do
|
||||||
%{user: user, conn: conn} = oauth_access(["read:statuses"])
|
%{user: user, conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
@ -102,6 +91,106 @@ test "the public timeline includes only public statuses for an authenticated use
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp local_and_remote_activities do
|
||||||
|
insert(:note_activity)
|
||||||
|
insert(:note_activity, local: false)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "public with restrict unauthenticated timeline for local and federated timelines" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :timelines, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :timelines, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :timelines, :federated]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :timelines, :federated], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn} do
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated" do
|
||||||
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "public with restrict unauthenticated timeline for local" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :timelines, :local]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :timelines, :local], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn} do
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{conn: _conn} do
|
||||||
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "public with restrict unauthenticated timeline for remote" do
|
||||||
|
setup do: local_and_remote_activities()
|
||||||
|
|
||||||
|
clear_config([:restrict_unauthenticated, :timelines, :federated]) do
|
||||||
|
Config.put([:restrict_unauthenticated, :timelines, :federated], true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is unauthenticated", %{conn: conn} do
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
|
||||||
|
assert json_response(res_conn, :unauthorized) == %{
|
||||||
|
"error" => "authorization required for timeline view"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if user is authenticated", %{conn: _conn} do
|
||||||
|
%{conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 1
|
||||||
|
|
||||||
|
res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"})
|
||||||
|
assert length(json_response(res_conn, 200)) == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "direct" do
|
describe "direct" do
|
||||||
test "direct timeline", %{conn: conn} do
|
test "direct timeline", %{conn: conn} do
|
||||||
user_one = insert(:user)
|
user_one = insert(:user)
|
||||||
|
|
Loading…
Reference in New Issue