summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/Admin-API.md34
-rw-r--r--lib/pleroma/activity.ex153
-rw-r--r--lib/pleroma/notification.ex11
-rw-r--r--lib/pleroma/object.ex75
-rw-r--r--lib/pleroma/uploaders/s3.ex13
-rw-r--r--lib/pleroma/user.ex104
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex58
-rw-r--r--lib/pleroma/web/activity_pub/mrf/keyword_policy.ex23
-rw-r--r--lib/pleroma/web/activity_pub/relay.ex2
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex6
-rw-r--r--lib/pleroma/web/activity_pub/views/object_view.ex4
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex23
-rw-r--r--lib/pleroma/web/admin_api/admin_api_controller.ex51
-rw-r--r--lib/pleroma/web/admin_api/search.ex54
-rw-r--r--lib/pleroma/web/common_api/common_api.ex14
-rw-r--r--lib/pleroma/web/common_api/utils.ex9
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex31
-rw-r--r--lib/pleroma/web/mastodon_api/views/app_view.ex41
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex2
-rw-r--r--lib/pleroma/web/oauth/oauth_controller.ex12
-rw-r--r--lib/pleroma/web/ostatus/handlers/note_handler.ex2
-rw-r--r--lib/pleroma/web/ostatus/ostatus.ex10
-rw-r--r--lib/pleroma/web/ostatus/ostatus_controller.ex13
-rw-r--r--lib/pleroma/web/rich_media/helpers.ex6
-rw-r--r--lib/pleroma/web/router.ex2
-rw-r--r--lib/pleroma/web/streamer.ex2
-rw-r--r--lib/pleroma/web/twitter_api/representers/activity_representer.ex15
-rw-r--r--lib/pleroma/web/twitter_api/views/activity_view.ex2
-rw-r--r--mix.exs1
-rw-r--r--priv/repo/migrations/20190325185009_create_notification_id_index.exs7
-rw-r--r--test/tasks/relay_test.exs3
-rw-r--r--test/user_test.exs18
-rw-r--r--test/web/activity_pub/activity_pub_test.exs130
-rw-r--r--test/web/activity_pub/views/user_view_test.exs23
-rw-r--r--test/web/admin_api/admin_api_controller_test.exs75
-rw-r--r--test/web/admin_api/search_test.exs88
-rw-r--r--test/web/mastodon_api/mastodon_api_controller_test.exs70
-rw-r--r--test/web/oauth/ldap_authorization_test.exs6
-rw-r--r--test/web/oauth/oauth_controller_test.exs4
-rw-r--r--test/web/twitter_api/representers/activity_representer_test.exs170
-rw-r--r--test/web/twitter_api/twitter_api_controller_test.exs63
41 files changed, 1042 insertions, 388 deletions
diff --git a/docs/Admin-API.md b/docs/Admin-API.md
index 2edb31f3c..53b68ffd4 100644
--- a/docs/Admin-API.md
+++ b/docs/Admin-API.md
@@ -8,10 +8,15 @@ Authentication is required and the user must be an admin.
- Method `GET`
- Query Params:
- - `query`: **string** *optional* search term
- - `local_only`: **bool** *optional* whether to return only local users
- - `page`: **integer** *optional* page number
- - `page_size`: **integer** *optional* number of users per page (default is `50`)
+ - *optional* `query`: **string** search term
+ - *optional* `filters`: **string** comma-separated string of filters:
+ - `local`: only local users
+ - `external`: only external users
+ - `active`: only active users
+ - `deactivated`: only deactivated users
+ - *optional* `page`: **integer** page number
+ - *optional* `page_size`: **integer** number of users per page (default is `50`)
+- Example: `https://mypleroma.org/api/pleroma/admin/users?query=john&filters=local,active&page=1&page_size=10`
- Response:
```JSON
@@ -22,7 +27,13 @@ Authentication is required and the user must be an admin.
{
"deactivated": bool,
"id": integer,
- "nickname": string
+ "nickname": string,
+ "roles": {
+ "admin": bool,
+ "moderator": bool
+ },
+ "local": bool,
+ "tags": array
},
...
]
@@ -99,7 +110,7 @@ Authentication is required and the user must be an admin.
Note: Available `:permission_group` is currently moderator and admin. 404 is returned when the permission group doesn’t exist.
-### Get user user permission groups membership
+### Get user user permission groups membership per permission group
- Method: `GET`
- Params: none
@@ -138,6 +149,17 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
- `nickname`
- `status` BOOLEAN field, false value means deactivation.
+## `/api/pleroma/admin/users/:nickname`
+
+### Retrive the details of a user
+
+- Method: `GET`
+- Params:
+ - `nickname`
+- Response:
+ - On failure: `Not found`
+ - On success: JSON of the user
+
## `/api/pleroma/admin/relay`
### Follow a Relay
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index 04c3bb673..bc3f8caba 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Activity do
alias Pleroma.Activity
alias Pleroma.Notification
+ alias Pleroma.Object
alias Pleroma.Repo
import Ecto.Query
@@ -33,9 +34,42 @@ defmodule Pleroma.Activity do
field(:recipients, {:array, :string})
has_many(:notifications, Notification, on_delete: :delete_all)
+ # Attention: this is a fake relation, don't try to preload it blindly and expect it to work!
+ # The foreign key is embedded in a jsonb field.
+ #
+ # To use it, you probably want to do an inner join and a preload:
+ #
+ # ```
+ # |> join(:inner, [activity], o in Object,
+ # on: fragment("(?->>'id') = COALESCE((?)->'object'->> 'id', (?)->>'object')",
+ # o.data, activity.data, activity.data))
+ # |> preload([activity, object], [object: object])
+ # ```
+ #
+ # As a convenience, Activity.with_preloaded_object() sets up an inner join and preload for the
+ # typical case.
+ has_one(:object, Object, on_delete: :nothing, foreign_key: :id)
+
timestamps()
end
+ def with_preloaded_object(query) do
+ query
+ |> join(
+ :inner,
+ [activity],
+ o in Object,
+ on:
+ fragment(
+ "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')",
+ o.data,
+ activity.data,
+ activity.data
+ )
+ )
+ |> preload([activity, object], object: object)
+ end
+
def get_by_ap_id(ap_id) do
Repo.one(
from(
@@ -45,10 +79,44 @@ defmodule Pleroma.Activity do
)
end
+ def get_by_ap_id_with_object(ap_id) do
+ Repo.one(
+ from(
+ activity in Activity,
+ where: fragment("(?)->>'id' = ?", activity.data, ^to_string(ap_id)),
+ left_join: o in Object,
+ on:
+ fragment(
+ "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')",
+ o.data,
+ activity.data,
+ activity.data
+ ),
+ preload: [object: o]
+ )
+ )
+ end
+
def get_by_id(id) do
Repo.get(Activity, id)
end
+ def get_by_id_with_object(id) do
+ from(activity in Activity,
+ where: activity.id == ^id,
+ inner_join: o in Object,
+ on:
+ fragment(
+ "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')",
+ o.data,
+ activity.data,
+ activity.data
+ ),
+ preload: [object: o]
+ )
+ |> Repo.one()
+ end
+
def by_object_ap_id(ap_id) do
from(
activity in Activity,
@@ -76,7 +144,7 @@ defmodule Pleroma.Activity do
)
end
- def create_by_object_ap_id(ap_id) do
+ def create_by_object_ap_id(ap_id) when is_binary(ap_id) do
from(
activity in Activity,
where:
@@ -90,6 +158,8 @@ defmodule Pleroma.Activity do
)
end
+ def create_by_object_ap_id(_), do: nil
+
def get_all_create_by_object_ap_id(ap_id) do
Repo.all(create_by_object_ap_id(ap_id))
end
@@ -101,8 +171,39 @@ defmodule Pleroma.Activity do
def get_create_by_object_ap_id(_), do: nil
- def normalize(obj) when is_map(obj), do: Activity.get_by_ap_id(obj["id"])
- def normalize(ap_id) when is_binary(ap_id), do: Activity.get_by_ap_id(ap_id)
+ def create_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do
+ from(
+ activity in Activity,
+ where:
+ fragment(
+ "coalesce((?)->'object'->>'id', (?)->>'object') = ?",
+ activity.data,
+ activity.data,
+ ^to_string(ap_id)
+ ),
+ where: fragment("(?)->>'type' = 'Create'", activity.data),
+ inner_join: o in Object,
+ on:
+ fragment(
+ "(?->>'id') = COALESCE(?->'object'->>'id', ?->>'object')",
+ o.data,
+ activity.data,
+ activity.data
+ ),
+ preload: [object: o]
+ )
+ end
+
+ def create_by_object_ap_id_with_object(_), do: nil
+
+ def get_create_by_object_ap_id_with_object(ap_id) do
+ ap_id
+ |> create_by_object_ap_id_with_object()
+ |> Repo.one()
+ end
+
+ def normalize(obj) when is_map(obj), do: get_by_ap_id_with_object(obj["id"])
+ def normalize(ap_id) when is_binary(ap_id), do: get_by_ap_id_with_object(ap_id)
def normalize(_), do: nil
def get_in_reply_to_activity(%Activity{data: %{"object" => %{"inReplyTo" => ap_id}}}) do
@@ -144,4 +245,50 @@ defmodule Pleroma.Activity do
|> where([s], s.actor == ^actor)
|> Repo.all()
end
+
+ def increase_replies_count(id) do
+ Activity
+ |> where(id: ^id)
+ |> update([a],
+ set: [
+ data:
+ fragment(
+ """
+ jsonb_set(?, '{object, repliesCount}',
+ (coalesce((?->'object'->>'repliesCount')::int, 0) + 1)::varchar::jsonb, true)
+ """,
+ a.data,
+ a.data
+ )
+ ]
+ )
+ |> Repo.update_all([])
+ |> case do
+ {1, [activity]} -> activity
+ _ -> {:error, "Not found"}
+ end
+ end
+
+ def decrease_replies_count(id) do
+ Activity
+ |> where(id: ^id)
+ |> update([a],
+ set: [
+ data:
+ fragment(
+ """
+ jsonb_set(?, '{object, repliesCount}',
+ (greatest(0, (?->'object'->>'repliesCount')::int - 1))::varchar::jsonb, true)
+ """,
+ a.data,
+ a.data
+ )
+ ]
+ )
+ |> Repo.update_all([])
+ |> case do
+ {1, [activity]} -> activity
+ _ -> {:error, "Not found"}
+ end
+ end
end
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index a98649b63..cac10f24a 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Notification do
alias Pleroma.Activity
alias Pleroma.Notification
+ alias Pleroma.Object
alias Pleroma.Pagination
alias Pleroma.Repo
alias Pleroma.User
@@ -33,7 +34,15 @@ defmodule Pleroma.Notification do
Notification
|> where(user_id: ^user.id)
|> join(:inner, [n], activity in assoc(n, :activity))
- |> preload(:activity)
+ |> join(:left, [n, a], object in Object,
+ on:
+ fragment(
+ "(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)",
+ object.data,
+ a.data
+ )
+ )
+ |> preload([n, a, o], activity: {a, object: o})
end
def for_user(user, opts \\ %{}) do
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
index 58e46ef1d..8a670645d 100644
--- a/lib/pleroma/object.ex
+++ b/lib/pleroma/object.ex
@@ -14,6 +14,8 @@ defmodule Pleroma.Object do
import Ecto.Query
import Ecto.Changeset
+ require Logger
+
schema "objects" do
field(:data, :map)
@@ -38,6 +40,33 @@ defmodule Pleroma.Object do
Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id)))
end
+ # If we pass an Activity to Object.normalize(), we can try to use the preloaded object.
+ # Use this whenever possible, especially when walking graphs in an O(N) loop!
+ def normalize(%Activity{object: %Object{} = object}), do: object
+
+ # Catch and log Object.normalize() calls where the Activity's child object is not
+ # preloaded.
+ def normalize(%Activity{data: %{"object" => %{"id" => ap_id}}}) do
+ Logger.debug(
+ "Object.normalize() called without preloaded object (#{ap_id}). Consider preloading the object!"
+ )
+
+ Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}")
+
+ normalize(ap_id)
+ end
+
+ def normalize(%Activity{data: %{"object" => ap_id}}) do
+ Logger.debug(
+ "Object.normalize() called without preloaded object (#{ap_id}). Consider preloading the object!"
+ )
+
+ Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}")
+
+ normalize(ap_id)
+ end
+
+ # Old way, try fetching the object through cache.
def normalize(%{"id" => ap_id}), do: normalize(ap_id)
def normalize(ap_id) when is_binary(ap_id), do: get_cached_by_ap_id(ap_id)
def normalize(_), do: nil
@@ -104,4 +133,50 @@ defmodule Pleroma.Object do
e -> e
end
end
+
+ def increase_replies_count(ap_id) do
+ Object
+ |> where([o], fragment("?->>'id' = ?::text", o.data, ^to_string(ap_id)))
+ |> update([o],
+ set: [
+ data:
+ fragment(
+ """
+ jsonb_set(?, '{repliesCount}',
+ (coalesce((?->>'repliesCount')::int, 0) + 1)::varchar::jsonb, true)
+ """,
+ o.data,
+ o.data
+ )
+ ]
+ )
+ |> Repo.update_all([])
+ |> case do
+ {1, [object]} -> set_cache(object)
+ _ -> {:error, "Not found"}
+ end
+ end
+
+ def decrease_replies_count(ap_id) do
+ Object
+ |> where([o], fragment("?->>'id' = ?::text", o.data, ^to_string(ap_id)))
+ |> update([o],
+ set: [
+ data:
+ fragment(
+ """
+ jsonb_set(?, '{repliesCount}',
+ (greatest(0, (?->>'repliesCount')::int - 1))::varchar::jsonb, true)
+ """,
+ o.data,
+ o.data
+ )
+ ]
+ )
+ |> Repo.update_all([])
+ |> case do
+ {1, [object]} -> set_cache(object)
+ _ -> {:error, "Not found"}
+ end
+ end
end
diff --git a/lib/pleroma/uploaders/s3.ex b/lib/pleroma/uploaders/s3.ex
index e7de3f3e0..521daa93b 100644
--- a/lib/pleroma/uploaders/s3.ex
+++ b/lib/pleroma/uploaders/s3.ex
@@ -13,10 +13,15 @@ defmodule Pleroma.Uploaders.S3 do
bucket = Keyword.fetch!(config, :bucket)
bucket_with_namespace =
- if namespace = Keyword.get(config, :bucket_namespace) do
- namespace <> ":" <> bucket
- else
- bucket
+ cond do
+ truncated_namespace = Keyword.get(config, :truncated_namespace) ->
+ truncated_namespace
+
+ namespace = Keyword.get(config, :bucket_namespace) ->
+ namespace <> ":" <> bucket
+
+ true ->
+ bucket
end
{:ok,
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index f2ef0a838..728b00a56 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -60,14 +60,10 @@ defmodule Pleroma.User do
timestamps()
end
- def auth_active?(%User{local: false}), do: true
-
- def auth_active?(%User{info: %User.Info{confirmation_pending: false}}), do: true
-
def auth_active?(%User{info: %User.Info{confirmation_pending: true}}),
do: !Pleroma.Config.get([:instance, :account_activation_required])
- def auth_active?(_), do: false
+ def auth_active?(%User{}), do: true
def visible_for?(user, for_user \\ nil)
@@ -83,17 +79,17 @@ defmodule Pleroma.User do
def superuser?(%User{local: true, info: %User.Info{is_moderator: true}}), do: true
def superuser?(_), do: false
- def avatar_url(user) do
+ def avatar_url(user, options \\ []) do
case user.avatar do
%{"url" => [%{"href" => href} | _]} -> href
- _ -> "#{Web.base_url()}/images/avi.png"
+ _ -> !options[:no_default] && "#{Web.base_url()}/images/avi.png"
end
end
- def banner_url(user) do
+ def banner_url(user, options \\ []) do
case user.info.banner do
%{"url" => [%{"href" => href} | _]} -> href
- _ -> "#{Web.base_url()}/images/banner.png"
+ _ -> !options[:no_default] && "#{Web.base_url()}/images/banner.png"
end
end
@@ -772,52 +768,6 @@ defmodule Pleroma.User do
Repo.all(query)
end
- @spec search_for_admin(%{
- local: boolean(),
- page: number(),
- page_size: number()
- }) :: {:ok, [Pleroma.User.t()], number()}
- def search_for_admin(%{query: nil, local: local, page: page, page_size: page_size}) do
- query =
- from(u in User, order_by: u.nickname)
- |> maybe_local_user_query(local)
-
- paginated_query =
- query
- |> paginate(page, page_size)
-
- count =
- query
- |> Repo.aggregate(:count, :id)
-
- {:ok, Repo.all(paginated_query), count}
- end
-
- @spec search_for_admin(%{
- query: binary(),
- local: boolean(),
- page: number(),
- page_size: number()
- }) :: {:ok, [Pleroma.User.t()], number()}
- def search_for_admin(%{
- query: term,
- local: local,
- page: page,
- page_size: page_size
- }) do
- maybe_local_query = User |> maybe_local_user_query(local)
-
- search_query = from(u in maybe_local_query, where: ilike(u.nickname, ^"%#{term}%"))
- count = search_query |> Repo.aggregate(:count, :id)
-
- results =
- search_query
- |> paginate(page, page_size)
- |> Repo.all()
-
- {:ok, results, count}
- end
-
def search(query, resolve \\ false, for_user \\ nil) do
# Strip the beginning @ off if there is a query
query = String.trim_leading(query, "@")
@@ -856,7 +806,7 @@ defmodule Pleroma.User do
search_rank:
fragment(
"""
- CASE WHEN (?) THEN (?) * 1.3
+ CASE WHEN (?) THEN (?) * 1.3
WHEN (?) THEN (?) * 1.2
WHEN (?) THEN (?) * 1.1
ELSE (?) END
@@ -1071,6 +1021,42 @@ defmodule Pleroma.User do
)
end
+ def maybe_external_user_query(query, external) do
+ if external, do: external_user_query(query), else: query
+ end
+
+ def external_user_query(query \\ User) do
+ from(
+ u in query,
+ where: u.local == false,
+ where: not is_nil(u.nickname)
+ )
+ end
+
+ def maybe_active_user_query(query, active) do
+ if active, do: active_user_query(query), else: query
+ end
+
+ def active_user_query(query \\ User) do
+ from(
+ u in query,
+ where: fragment("not (?->'deactivated' @> 'true')", u.info),
+ where: not is_nil(u.nickname)
+ )
+ end
+
+ def maybe_deactivated_user_query(query, deactivated) do
+ if deactivated, do: deactivated_user_query(query), else: query
+ end
+
+ def deactivated_user_query(query \\ User) do
+ from(
+ u in query,
+ where: fragment("(?->'deactivated' @> 'true')", u.info),
+ where: not is_nil(u.nickname)
+ )
+ end
+
def active_local_user_query do
from(
u in local_user_query(),
@@ -1110,13 +1096,15 @@ defmodule Pleroma.User do
friends
|> Enum.each(fn followed -> User.unfollow(user, followed) end)
- query = from(a in Activity, where: a.actor == ^user.ap_id)
+ query =
+ from(a in Activity, where: a.actor == ^user.ap_id)
+ |> Activity.with_preloaded_object()
Repo.all(query)
|> Enum.each(fn activity ->
case activity.data["type"] do
"Create" ->
- ActivityPub.delete(Object.normalize(activity.data["object"]))
+ ActivityPub.delete(Object.normalize(activity))
# TODO: Do something with likes, follows, repeats.
_ ->
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 2470b4a71..6e1ed7ec9 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -89,13 +89,37 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
if is_public?(object), do: User.decrease_note_count(actor), else: {:ok, actor}
end
+ def increase_replies_count_if_reply(%{
+ "object" =>
+ %{"inReplyTo" => reply_ap_id, "inReplyToStatusId" => reply_status_id} = object,
+ "type" => "Create"
+ }) do
+ if is_public?(object) do
+ Activity.increase_replies_count(reply_status_id)
+ Object.increase_replies_count(reply_ap_id)
+ end
+ end
+
+ def increase_replies_count_if_reply(_create_data), do: :noop
+
+ def decrease_replies_count_if_reply(%Object{
+ data: %{"inReplyTo" => reply_ap_id, "inReplyToStatusId" => reply_status_id} = object
+ }) do
+ if is_public?(object) do
+ Activity.decrease_replies_count(reply_status_id)
+ Object.decrease_replies_count(reply_ap_id)
+ end
+ end
+
+ def decrease_replies_count_if_reply(_object), do: :noop
+
def insert(map, local \\ true) when is_map(map) do
with nil <- Activity.normalize(map),
map <- lazy_put_activity_defaults(map),
:ok <- check_actor_is_active(map["actor"]),
{_, true} <- {:remote_limit_error, check_remote_limit(map)},
{:ok, map} <- MRF.filter(map),
- :ok <- insert_full_object(map) do
+ {:ok, object} <- insert_full_object(map) do
{recipients, _, _} = get_recipients(map)
{:ok, activity} =
@@ -106,6 +130,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
recipients: recipients
})
+ # Splice in the child object if we have one.
+ activity =
+ if !is_nil(object) do
+ Map.put(activity, :object, object)
+ else
+ activity
+ end
+
Task.start(fn ->
Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
end)
@@ -170,6 +202,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
additional
),
{:ok, activity} <- insert(create_data, local),
+ _ <- increase_replies_count_if_reply(create_data),
# Changing note count prior to enqueuing federation task in order to avoid
# race conditions on updating user.info
{:ok, _actor} <- increase_note_count_if_public(actor, activity),
@@ -321,6 +354,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
"deleted_activity_id" => activity && activity.id
},
{:ok, activity} <- insert(data, local),
+ _ <- decrease_replies_count_if_reply(object),
# Changing note count prior to enqueuing federation task in order to avoid
# race conditions on updating user.info
{:ok, _actor} <- decrease_note_count_if_public(user, object),
@@ -430,6 +464,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
),
order_by: [desc: :id]
)
+ |> Activity.with_preloaded_object()
Repo.all(query)
end
@@ -702,13 +737,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
from(
activity in query,
- where: fragment("not ?->>'type' = 'Announce'", activity.data),
- where: fragment("not ? = ANY(?)", activity.actor, ^muted_reblogs)
+ where:
+ fragment(
+ "not ( ?->>'type' = 'Announce' and ? = ANY(?))",
+ activity.data,
+ activity.actor,
+ ^muted_reblogs
+ )
)
end
defp restrict_muted_reblogs(query, _), do: query
+ defp maybe_preload_objects(query, %{"skip_preload" => true}), do: query
+
+ defp maybe_preload_objects(query, _) do
+ query
+ |> Activity.with_preloaded_object()
+ end
+
def fetch_activities_query(recipients, opts \\ %{}) do
base_query =
from(
@@ -718,6 +765,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
)
base_query
+ |> maybe_preload_objects(opts)
|> restrict_recipients(recipients, opts["user"])
|> restrict_tag(opts)
|> restrict_tag_reject(opts)
@@ -940,7 +988,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
},
:ok <- Transmogrifier.contain_origin(id, params),
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
- {:ok, Object.normalize(activity.data["object"])}
+ {:ok, Object.normalize(activity)}
else
{:error, {:reject, nil}} ->
{:reject, nil}
@@ -952,7 +1000,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
Logger.info("Couldn't get object via AP, trying out OStatus fetching...")
case OStatus.fetch_activity_from_url(id) do
- {:ok, [activity | _]} -> {:ok, Object.normalize(activity.data["object"])}
+ {:ok, [activity | _]} -> {:ok, Object.normalize(activity)}
e -> e
end
end
diff --git a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
index 25d5f9cd3..e8dfba672 100644
--- a/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
@@ -4,6 +4,10 @@
defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
@behaviour Pleroma.Web.ActivityPub.MRF
+ defp string_matches?(string, _) when not is_binary(string) do
+ false
+ end
+
defp string_matches?(string, pattern) when is_binary(pattern) do
String.contains?(string, pattern)
end
@@ -44,6 +48,20 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
end
defp check_replace(%{"object" => %{"content" => content, "summary" => summary}} = message) do
+ content =
+ if is_binary(content) do
+ content
+ else
+ ""
+ end
+
+ summary =
+ if is_binary(summary) do
+ summary
+ else
+ ""
+ end
+
{content, summary} =
Enum.reduce(
Pleroma.Config.get([:mrf_keyword, :replace]),
@@ -61,11 +79,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
end
@impl true
- def filter(%{"object" => %{"content" => nil}} = message) do
- {:ok, message}
- end
-
- @impl true
def filter(%{"type" => "Create", "object" => %{"content" => _content}} = message) do
with {:ok, message} <- check_reject(message),
{:ok, message} <- check_ftl_removal(message),
diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex
index 01fef71b9..a7a20ca37 100644
--- a/lib/pleroma/web/activity_pub/relay.ex
+++ b/lib/pleroma/web/activity_pub/relay.ex
@@ -41,7 +41,7 @@ defmodule Pleroma.Web.ActivityPub.Relay do
def publish(%Activity{data: %{"type" => "Create"}} = activity) do
with %User{} = user <- get_actor(),
- %Object{} = object <- Object.normalize(activity.data["object"]["id"]) do
+ %Object{} = object <- Object.normalize(activity) do
ActivityPub.announce(user, object, nil, true, false)
else
e -> Logger.error("error: #{inspect(e)}")
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index af317245f..2e9ffe41c 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -209,12 +209,12 @@ defmodule Pleroma.Web.ActivityPub.Utils do
"""
def insert_full_object(%{"object" => %{"type" => type} = object_data})
when is_map(object_data) and type in @supported_object_types do
- with {:ok, _} <- Object.create(object_data) do
- :ok
+ with {:ok, object} <- Object.create(object_data) do
+ {:ok, object}
end
end
- def insert_full_object(_), do: :ok
+ def insert_full_object(_), do: {:ok, nil}
def update_object_in_activities(%{data: %{"id" => id}} = object) do
# TODO
diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex
index 84fa94e32..6028b773c 100644
--- a/lib/pleroma/web/activity_pub/views/object_view.ex
+++ b/lib/pleroma/web/activity_pub/views/object_view.ex
@@ -17,7 +17,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
def render("object.json", %{object: %Activity{data: %{"type" => "Create"}} = activity}) do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
- object = Object.normalize(activity.data["object"])
+ object = Object.normalize(activity)
additional =
Transmogrifier.prepare_object(activity.data)
@@ -28,7 +28,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectView do
def render("object.json", %{object: %Activity{} = activity}) do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
- object = Object.normalize(activity.data["object"])
+ object = Object.normalize(activity)
additional =
Transmogrifier.prepare_object(activity.data)
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 3d00dcbf2..5926a3294 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -87,16 +87,10 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"publicKeyPem" => public_key
},
"endpoints" => endpoints,
- "icon" => %{
- "type" => "Image",
- "url" => User.avatar_url(user)
- },
- "image" => %{
- "type" => "Image",
- "url" => User.banner_url(user)
- },
"tag" => user.info.source_data["tag"] || []
}
+ |> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user))
+ |> Map.merge(maybe_make_image(&User.banner_url/2, "image", user))
|> Map.merge(Utils.make_json_ld_header())
end
@@ -294,4 +288,17 @@ defmodule Pleroma.Web.ActivityPub.UserView do
map
end
end
+
+ defp maybe_make_image(func, key, user) do
+ if image = func.(user, no_default: true) do
+ %{
+ key => %{
+ "type" => "Image",
+ "url" => image
+ }
+ }
+ else
+ %{}
+ end
+ end
end
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index 6d9bf2895..b3a09e49e 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -3,17 +3,18 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.AdminAPIController do
- @users_page_size 50
-
use Pleroma.Web, :controller
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.AdminAPI.AccountView
+ alias Pleroma.Web.AdminAPI.Search
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
require Logger
+ @users_page_size 50
+
action_fallback(:errors)
def user_delete(conn, %{"nickname" => nickname}) do
@@ -44,6 +45,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|> json(user.nickname)
end
+ def user_show(conn, %{"nickname" => nickname}) do
+ with %User{} = user <- User.get_by_nickname(nickname) do
+ conn
+ |> json(AccountView.render("show.json", %{user: user}))
+ else
+ _ -> {:error, :not_found}
+ end
+ end
+
def user_toggle_activation(conn, %{"nickname" => nickname}) do
user = User.get_by_nickname(nickname)
@@ -63,17 +73,17 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
do: json_response(conn, :no_content, "")
end
- def list_users(%{assigns: %{user: admin}} = conn, params) do
+ def list_users(conn, params) do
{page, page_size} = page_params(params)
+ filters = maybe_parse_filters(params["filters"])
- with {:ok, users, count} <-
- User.search_for_admin(%{
- query: params["query"],
- admin: admin,
- local: params["local_only"] == "true",
- page: page,
- page_size: page_size
- }),
+ search_params = %{
+ query: params["query"],
+ page: page,
+ page_size: page_size
+ }
+
+ with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
do:
conn
|> json(
@@ -85,6 +95,19 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
)
end
+ @filters ~w(local external active deactivated)
+
+ defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
+
+ @spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
+ defp maybe_parse_filters(filters) do
+ filters
+ |> String.split(",")
+ |> Enum.filter(&Enum.member?(@filters, &1))
+ |> Enum.map(&String.to_atom(&1))
+ |> Enum.into(%{}, &{&1, true})
+ end
+
def right_add(conn, %{"permission_group" => permission_group, "nickname" => nickname})
when permission_group in ["moderator", "admin"] do
user = User.get_by_nickname(nickname)
@@ -217,6 +240,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|> json(token.token)
end
+ def errors(conn, {:error, :not_found}) do
+ conn
+ |> put_status(404)
+ |> json("Not found")
+ end
+
def errors(conn, {:param_cast, _}) do
conn
|> put_status(400)
diff --git a/lib/pleroma/web/admin_api/search.ex b/lib/pleroma/web/admin_api/search.ex
new file mode 100644
index 000000000..9a8e41c2a
--- /dev/null
+++ b/lib/pleroma/web/admin_api/search.ex
@@ -0,0 +1,54 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.Search do
+ import Ecto.Query
+
+ alias Pleroma.Repo
+ alias Pleroma.User
+
+ @page_size 50
+
+ def user(%{query: term} = params) when is_nil(term) or term == "" do
+ query = maybe_filtered_query(params)
+
+ paginated_query =
+ maybe_filtered_query(params)
+ |> paginate(params[:page] || 1, params[:page_size] || @page_size)
+
+ count = query |> Repo.aggregate(:count, :id)
+
+ results = Repo.all(paginated_query)
+
+ {:ok, results, count}
+ end
+
+ def user(%{query: term} = params) when is_binary(term) do
+ search_query = from(u in maybe_filtered_query(params), where: ilike(u.nickname, ^"%#{term}%"))
+
+ count = search_query |> Repo.aggregate(:count, :id)
+
+ results =
+ search_query
+ |> paginate(params[:page] || 1, params[:page_size] || @page_size)
+ |> Repo.all()
+
+ {:ok, results, count}
+ end
+
+ defp maybe_filtered_query(params) do
+ from(u in User, order_by: u.nickname)
+ |> User.maybe_local_user_query(params[:local])
+ |> User.maybe_external_user_query(params[:external])
+ |> User.maybe_active_user_query(params[:active])
+ |> User.maybe_deactivated_user_query(params[:deactivated])
+ end
+
+ defp paginate(query, page, page_size) do
+ from(u in query,
+ limit: ^page_size,
+ offset: ^((page - 1) * page_size)
+ )
+ end
+end
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 50d60aade..25b990677 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -6,7 +6,6 @@ defmodule Pleroma.Web.CommonAPI do
alias Pleroma.Activity
alias Pleroma.Formatter
alias Pleroma.Object
- alias Pleroma.Repo
alias Pleroma.ThreadMute
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@@ -64,8 +63,9 @@ defmodule Pleroma.Web.CommonAPI do
end
def delete(activity_id, user) do
- with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
- %Object{} = object <- Object.normalize(object_id),
+ with %Activity{data: %{"object" => _}} = activity <-
+ Activity.get_by_id_with_object(activity_id),
+ %Object{} = object <- Object.normalize(activity),
true <- User.superuser?(user) || user.ap_id == object.data["actor"],
{:ok, _} <- unpin(activity_id, user),
{:ok, delete} <- ActivityPub.delete(object) do
@@ -75,7 +75,7 @@ defmodule Pleroma.Web.CommonAPI do
def repeat(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
- object <- Object.normalize(activity.data["object"]["id"]),
+ object <- Object.normalize(activity),
nil <- Utils.get_existing_announce(user.ap_id, object) do
ActivityPub.announce(user, object)
else
@@ -86,7 +86,7 @@ defmodule Pleroma.Web.CommonAPI do
def unrepeat(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
- object <- Object.normalize(activity.data["object"]["id"]) do
+ object <- Object.normalize(activity) do
ActivityPub.unannounce(user, object)
else
_ ->
@@ -96,7 +96,7 @@ defmodule Pleroma.Web.CommonAPI do
def favorite(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
- object <- Object.normalize(activity.data["object"]["id"]),
+ object <- Object.normalize(activity),
nil <- Utils.get_existing_like(user.ap_id, object) do
ActivityPub.like(user, object)
else
@@ -107,7 +107,7 @@ defmodule Pleroma.Web.CommonAPI do
def unfavorite(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
- object <- Object.normalize(activity.data["object"]["id"]) do
+ object <- Object.normalize(activity) do
ActivityPub.unlike(user, object)
else
_ ->
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index 3e807a5b7..f596f703b 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -17,13 +17,14 @@ defmodule Pleroma.Web.CommonAPI.Utils do
# This is a hack for twidere.
def get_by_id_or_ap_id(id) do
- activity = Repo.get(Activity, id) || Activity.get_create_by_object_ap_id(id)
+ activity =
+ Activity.get_by_id_with_object(id) || Activity.get_create_by_object_ap_id_with_object(id)
activity &&
if activity.data["type"] == "Create" do
activity
else
- Activity.get_create_by_object_ap_id(activity.data["object"])
+ Activity.get_create_by_object_ap_id_with_object(activity.data["object"])
end
end
@@ -302,10 +303,10 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def maybe_notify_mentioned_recipients(
recipients,
- %Activity{data: %{"to" => _to, "type" => type} = data} = _activity
+ %Activity{data: %{"to" => _to, "type" => type} = data} = activity
)
when type == "Create" do
- object = Object.normalize(data["object"])
+ object = Object.normalize(activity)
object_data =
cond do
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 2eb1da561..eee4e7678 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -18,6 +18,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.MastodonAPI.AppView
alias Pleroma.Web.MastodonAPI.FilterView
alias Pleroma.Web.MastodonAPI.ListView
alias Pleroma.Web.MastodonAPI.MastodonAPI
@@ -51,16 +52,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
with cs <- App.register_changeset(%App{}, app_attrs),
false <- cs.changes[:client_name] == @local_mastodon_name,
{:ok, app} <- Repo.insert(cs) do
- res = %{
- id: app.id |> to_string,
- name: app.client_name,
- client_id: app.client_id,
- client_secret: app.client_secret,
- redirect_uri: app.redirect_uris,
- website: app.website
- }
-
- json(conn, res)
+ conn
+ |> put_view(AppView)
+ |> render("show.json", %{app: app})
end
end
@@ -132,6 +126,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
json(conn, account)
end
+ def verify_app_credentials(%{assigns: %{user: _user, token: token}} = conn, _) do
+ with %Token{app: %App{} = app} <- Repo.preload(token, :app) do
+ conn
+ |> put_view(AppView)
+ |> render("short.json", %{app: app})
+ end
+ end
+
def user(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id),
true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do
@@ -161,6 +163,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
},
stats: Stats.get_stats(),
thumbnail: Web.base_url() <> "/instance/thumbnail.jpeg",
+ languages: ["en"],
+ registrations: Pleroma.Config.get([:instance, :registrations_open]),
+ # Extra (not present in Mastodon):
max_toot_chars: Keyword.get(instance, :limit)
}
@@ -944,12 +949,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def favourites(%{assigns: %{user: user}} = conn, params) do
- activities =
+ params =
params
|> Map.put("type", "Create")
|> Map.put("favorited_by", user.ap_id)
|> Map.put("blocking_user", user)
- |> ActivityPub.fetch_public_activities()
+
+ activities =
+ ActivityPub.fetch_activities([], params)
|> Enum.reverse()
conn
diff --git a/lib/pleroma/web/mastodon_api/views/app_view.ex b/lib/pleroma/web/mastodon_api/views/app_view.ex
new file mode 100644
index 000000000..f52b693a6
--- /dev/null
+++ b/lib/pleroma/web/mastodon_api/views/app_view.ex
@@ -0,0 +1,41 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.AppView do
+ use Pleroma.Web, :view
+
+ alias Pleroma.Web.OAuth.App
+
+ @vapid_key :web_push_encryption
+ |> Application.get_env(:vapid_details, [])
+ |> Keyword.get(:public_key)
+
+ def render("show.json", %{app: %App{} = app}) do
+ %{
+ id: app.id |> to_string,
+ name: app.client_name,
+ client_id: app.client_id,
+ client_secret: app.client_secret,
+ redirect_uri: app.redirect_uris,
+ website: app.website
+ }
+ |> with_vapid_key()
+ end
+
+ def render("short.json", %{app: %App{website: webiste, client_name: name}}) do
+ %{
+ name: name,
+ website: webiste
+ }
+ |> with_vapid_key()
+ end
+
+ defp with_vapid_key(data) do
+ if @vapid_key do
+ Map.put(data, "vapid_key", @vapid_key)
+ else
+ data
+ end
+ end
+end
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index 1ca8338cc..200bb453d 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -174,7 +174,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
content: content,
created_at: created_at,
reblogs_count: announcement_count,
- replies_count: 0,
+ replies_count: object["repliesCount"] || 0,
favourites_count: like_count,
reblogged: present?(repeated),
favourited: present?(favorited),
diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex
index d151efe9e..ebb3dd253 100644
--- a/lib/pleroma/web/oauth/oauth_controller.ex
+++ b/lib/pleroma/web/oauth/oauth_controller.ex
@@ -83,14 +83,18 @@ defmodule Pleroma.Web.OAuth.OAuthController do
end
else
{scopes_issue, _} when scopes_issue in [:unsupported_scopes, :missing_scopes] ->
+ # Per https://github.com/tootsuite/mastodon/blob/
+ # 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L39
conn
- |> put_flash(:error, "Permissions not specified.")
+ |> put_flash(:error, "This action is outside the authorized scopes")
|> put_status(:unauthorized)
|> authorize(auth_params)
{:auth_active, false} ->
+ # Per https://github.com/tootsuite/mastodon/blob/
+ # 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L76
conn
- |> put_flash(:error, "Account confirmation pending.")
+ |> put_flash(:error, "Your login is missing a confirmed e-mail address")
|> put_status(:forbidden)
|> authorize(auth_params)
@@ -149,9 +153,11 @@ defmodule Pleroma.Web.OAuth.OAuthController do
json(conn, response)
else
{:auth_active, false} ->
+ # Per https://github.com/tootsuite/mastodon/blob/
+ # 51e154f5e87968d6bb115e053689767ab33e80cd/app/controllers/api/base_controller.rb#L76
conn
|> put_status(:forbidden)
- |> json(%{error: "Account confirmation pending"})
+ |> json(%{error: "Your login is missing a confirmed e-mail address"})
_error ->
put_status(conn, 400)
diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex
index 770a71a0a..db995ec77 100644
--- a/lib/pleroma/web/ostatus/handlers/note_handler.ex
+++ b/lib/pleroma/web/ostatus/handlers/note_handler.ex
@@ -106,7 +106,7 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
# TODO: Clean this up a bit.
def handle_note(entry, doc \\ nil) do
with id <- XML.string_from_xpath("//id", entry),
- activity when is_nil(activity) <- Activity.get_create_by_object_ap_id(id),
+ activity when is_nil(activity) <- Activity.get_create_by_object_ap_id_with_object(id),
[author] <- :xmerl_xpath.string('//author[1]', doc),
{:ok, actor} <- OStatus.find_make_or_update_user(author),
content_html <- OStatus.get_content(entry),
diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex
index 266f86bf4..9a34d7ad5 100644
--- a/lib/pleroma/web/ostatus/ostatus.ex
+++ b/lib/pleroma/web/ostatus/ostatus.ex
@@ -23,8 +23,8 @@ defmodule Pleroma.Web.OStatus do
alias Pleroma.Web.WebFinger
alias Pleroma.Web.Websub
- def is_representable?(%Activity{data: data}) do
- object = Object.normalize(data["object"])
+ def is_representable?(%Activity{} = activity) do
+ object = Object.normalize(activity)
cond do
is_nil(object) ->
@@ -119,7 +119,7 @@ defmodule Pleroma.Web.OStatus do
def make_share(entry, doc, retweeted_activity) do
with {:ok, actor} <- find_make_or_update_user(doc),
- %Object{} = object <- Object.normalize(retweeted_activity.data["object"]),
+ %Object{} = object <- Object.normalize(retweeted_activity),
id when not is_nil(id) <- string_from_xpath("/entry/id", entry),
{:ok, activity, _object} = ActivityPub.announce(actor, object, id, false) do
{:ok, activity}
@@ -137,7 +137,7 @@ defmodule Pleroma.Web.OStatus do
def make_favorite(entry, doc, favorited_activity) do
with {:ok, actor} <- find_make_or_update_user(doc),
- %Object{} = object <- Object.normalize(favorited_activity.data["object"]),
+ %Object{} = object <- Object.normalize(favorited_activity),
id when not is_nil(id) <- string_from_xpath("/entry/id", entry),
{:ok, activity, _object} = ActivityPub.like(actor, object, id, false) do
{:ok, activity}
@@ -159,7 +159,7 @@ defmodule Pleroma.Web.OStatus do
Logger.debug("Trying to get entry from db")
with id when not is_nil(id) <- string_from_xpath("//activity:object[1]/id", entry),
- %Activity{} = activity <- Activity.get_create_by_object_ap_id(id) do
+ %Activity{} = activity <- Activity.get_create_by_object_ap_id_with_object(id) do
{:ok, activity}
else
_ ->
diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex
index 0579a5f3d..2fb6ce41b 100644
--- a/lib/pleroma/web/ostatus/ostatus_controller.ex
+++ b/lib/pleroma/web/ostatus/ostatus_controller.ex
@@ -102,7 +102,8 @@ defmodule Pleroma.Web.OStatus.OStatusController do
ActivityPubController.call(conn, :object)
else
with id <- o_status_url(conn, :object, uuid),
- {_, %Activity{} = activity} <- {:activity, Activity.get_create_by_object_ap_id(id)},
+ {_, %Activity{} = activity} <-
+ {:activity, Activity.get_create_by_object_ap_id_with_object(id)},
{_, true} <- {:public?, Visibility.is_public?(activity)},
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
case get_format(conn) do
@@ -148,13 +149,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do
end
def notice(conn, %{"id" => id}) do
- with {_, %Activity{} = activity} <- {:activity, Activity.get_by_id(id)},
+ with {_, %Activity{} = activity} <- {:activity, Activity.get_by_id_with_object(id)},
{_, true} <- {:public?, Visibility.is_public?(activity)},
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
case format = get_format(conn) do
"html" ->
if activity.data["type"] == "Create" do
- %Object{} = object = Object.normalize(activity.data["object"])
+ %Object{} = object = Object.normalize(activity)
Fallback.RedirectController.redirector_with_meta(conn, %{
activity_id: activity.id,
@@ -191,9 +192,9 @@ defmodule Pleroma.Web.OStatus.OStatusController do
# Returns an HTML embedded <audio> or <video> player suitable for embed iframes.
def notice_player(conn, %{"id" => id}) do
- with %Activity{data: %{"type" => "Create"}} = activity <- Activity.get_by_id(id),
+ with %Activity{data: %{"type" => "Create"}} = activity <- Activity.get_by_id_with_object(id),
true <- Visibility.is_public?(activity),
- %Object{} = object <- Object.normalize(activity.data["object"]),
+ %Object{} = object <- Object.normalize(activity),
%{data: %{"attachment" => [%{"url" => [url | _]} | _]}} <- object,
true <- String.starts_with?(url["mediaType"], ["audio", "video"]) do
conn
@@ -219,7 +220,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
%Activity{data: %{"type" => "Create"}} = activity,
_user
) do
- object = Object.normalize(activity.data["object"])
+ object = Object.normalize(activity)
conn
|> put_resp_header("content-type", "application/activity+json")
diff --git a/lib/pleroma/web/rich_media/helpers.ex b/lib/pleroma/web/rich_media/helpers.ex
index 92c61ff51..f67aaf58b 100644
--- a/lib/pleroma/web/rich_media/helpers.ex
+++ b/lib/pleroma/web/rich_media/helpers.ex
@@ -21,9 +21,9 @@ defmodule Pleroma.Web.RichMedia.Helpers do
defp validate_page_url(%URI{}), do: :ok
defp validate_page_url(_), do: :error
- def fetch_data_for_activity(%Activity{} = activity) do
+ def fetch_data_for_activity(%Activity{data: %{"type" => "Create"}} = activity) do
with true <- Pleroma.Config.get([:rich_media, :enabled]),
- %Object{} = object <- Object.normalize(activity.data["object"]),
+ %Object{} = object <- Object.normalize(activity),
{:ok, page_url} <- HTML.extract_first_external_url(object, object.data["content"]),
:ok <- validate_page_url(page_url),
{:ok, rich_media} <- Parser.parse(page_url) do
@@ -32,4 +32,6 @@ defmodule Pleroma.Web.RichMedia.Helpers do
_ -> %{}
end
end
+
+ def fetch_data_for_activity(_), do: %{}
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index befd382ba..9ccb4e535 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -140,6 +140,7 @@ defmodule Pleroma.Web.Router do
pipe_through([:admin_api, :oauth_write])
get("/users", AdminAPIController, :list_users)
+ get("/users/:nickname", AdminAPIController, :user_show)
delete("/user", AdminAPIController, :user_delete)
patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation)
post("/user", AdminAPIController, :user_create)
@@ -328,6 +329,7 @@ defmodule Pleroma.Web.Router do
get("/instance", MastodonAPIController, :masto_instance)
get("/instance/peers", MastodonAPIController, :peers)
post("/apps", MastodonAPIController, :create_app)
+ get("/apps/verify_credentials", MastodonAPIController, :verify_app_credentials)
get("/custom_emojis", MastodonAPIController, :custom_emojis)
get("/statuses/:id/card", MastodonAPIController, :status_card)
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index 7425bfb54..592749b42 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -202,7 +202,7 @@ defmodule Pleroma.Web.Streamer do
mutes = user.info.mutes || []
reblog_mutes = user.info.muted_reblogs || []
- parent = Object.normalize(item.data["object"])
+ parent = Object.normalize(item)
unless is_nil(parent) or item.actor in blocks or item.actor in mutes or
item.actor in reblog_mutes or not ActivityPub.contain_activity(item, user) or
diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
deleted file mode 100644
index 55c612ddd..000000000
--- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex
+++ /dev/null
@@ -1,15 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-# FIXME: Remove this module?
-# THIS MODULE IS DEPRECATED! DON'T USE IT!
-# USE THE Pleroma.Web.TwitterAPI.Views.ActivityView MODULE!
-defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
- def to_map(activity, opts) do
- Pleroma.Web.TwitterAPI.ActivityView.render(
- "activity.json",
- Map.put(opts, :activity, activity)
- )
- end
-end
diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex
index fe7d49975..aa1d41fa2 100644
--- a/lib/pleroma/web/twitter_api/views/activity_view.ex
+++ b/lib/pleroma/web/twitter_api/views/activity_view.ex
@@ -266,6 +266,8 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
content
|> String.replace(~r/<br\s?\/?>/, "\n")
|> HTML.get_cached_stripped_html_for_object(activity, __MODULE__)
+ else
+ ""
end
reply_parent = Activity.get_in_reply_to_activity(activity)
diff --git a/mix.exs b/mix.exs
index 3f3c8cd35..99a262089 100644
--- a/mix.exs
+++ b/mix.exs
@@ -9,6 +9,7 @@ defmodule Pleroma.Mixfile do
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
elixirc_options: [warnings_as_errors: true],
+ xref: [exclude: [:eldap]],
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps(),
diff --git a/priv/repo/migrations/20190325185009_create_notification_id_index.exs b/priv/repo/migrations/20190325185009_create_notification_id_index.exs
new file mode 100644
index 000000000..a6ab38d02
--- /dev/null
+++ b/priv/repo/migrations/20190325185009_create_notification_id_index.exs
@@ -0,0 +1,7 @@
+defmodule Pleroma.Repo.Migrations.CreateNotificationIdIndex do
+ use Ecto.Migration
+
+ def change do
+ create index(:notifications, ["id desc nulls last"])
+ end
+end
diff --git a/test/tasks/relay_test.exs b/test/tasks/relay_test.exs
index c9d90fa2e..535dc3756 100644
--- a/test/tasks/relay_test.exs
+++ b/test/tasks/relay_test.exs
@@ -60,7 +60,8 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
ActivityPub.fetch_activities([], %{
"type" => "Undo",
"actor_id" => follower_id,
- "limit" => 1
+ "limit" => 1,
+ "skip_preload" => true
})
assert undo_activity.data["type"] == "Undo"
diff --git a/test/user_test.exs b/test/user_test.exs
index 442599910..8cf2ba6ab 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -8,6 +8,7 @@ defmodule Pleroma.UserTest do
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
+
use Pleroma.DataCase
import Pleroma.Factory
@@ -1107,21 +1108,4 @@ defmodule Pleroma.UserTest do
assert {:ok, user_state3} = User.bookmark(user, id2)
assert user_state3.bookmarks == [id2]
end
-
- describe "search for admin" do
- test "it ignores case" do
- insert(:user, nickname: "papercoach")
- insert(:user, nickname: "CanadaPaperCoach")
-
- {:ok, _results, count} =
- User.search_for_admin(%{
- query: "paper",
- local: false,
- page: 1,
- page_size: 50
- })
-
- assert count == 2
- end
- end
end
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 035778218..ac5fbe0a9 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -140,7 +140,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activity = insert(:note_activity)
{:ok, new_activity} = ActivityPub.insert(activity.data)
- assert activity == new_activity
+ assert activity.id == new_activity.id
end
test "inserts a given map into the activity database, giving it an id if it has none." do
@@ -232,6 +232,39 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = Repo.get(User, user.id)
assert user.info.note_count == 2
end
+
+ test "increases replies count" do
+ user = insert(:user)
+ user2 = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "1", "visibility" => "public"})
+ ap_id = activity.data["id"]
+ reply_data = %{"status" => "1", "in_reply_to_status_id" => activity.id}
+
+ # public
+ {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "public"))
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 1
+ assert object.data["repliesCount"] == 1
+
+ # unlisted
+ {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "unlisted"))
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 2
+ assert object.data["repliesCount"] == 2
+
+ # private
+ {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "private"))
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 2
+ assert object.data["repliesCount"] == 2
+
+ # direct
+ {:ok, _} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "direct"))
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 2
+ assert object.data["repliesCount"] == 2
+ end
end
describe "fetch activities for recipients" do
@@ -270,7 +303,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
booster = insert(:user)
{:ok, user} = User.block(user, %{ap_id: activity_one.data["actor"]})
- activities = ActivityPub.fetch_activities([], %{"blocking_user" => user})
+ activities =
+ ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@@ -278,7 +312,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = User.unblock(user, %{ap_id: activity_one.data["actor"]})
- activities = ActivityPub.fetch_activities([], %{"blocking_user" => user})
+ activities =
+ ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@@ -289,14 +324,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
%Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
activity_three = Repo.get(Activity, activity_three.id)
- activities = ActivityPub.fetch_activities([], %{"blocking_user" => user})
+ activities =
+ ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
refute Enum.member?(activities, activity_three)
refute Enum.member?(activities, boost_activity)
assert Enum.member?(activities, activity_one)
- activities = ActivityPub.fetch_activities([], %{"blocking_user" => nil})
+ activities =
+ ActivityPub.fetch_activities([], %{"blocking_user" => nil, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@@ -312,14 +349,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
booster = insert(:user)
{:ok, user} = User.mute(user, %User{ap_id: activity_one.data["actor"]})
- activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
+ activities =
+ ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
refute Enum.member?(activities, activity_one)
# Calling with 'with_muted' will deliver muted activities, too.
- activities = ActivityPub.fetch_activities([], %{"muting_user" => user, "with_muted" => true})
+ activities =
+ ActivityPub.fetch_activities([], %{
+ "muting_user" => user,
+ "with_muted" => true,
+ "skip_preload" => true
+ })
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@@ -327,7 +370,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = User.unmute(user, %User{ap_id: activity_one.data["actor"]})
- activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
+ activities =
+ ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@@ -338,14 +382,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
%Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
activity_three = Repo.get(Activity, activity_three.id)
- activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
+ activities =
+ ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
refute Enum.member?(activities, activity_three)
refute Enum.member?(activities, boost_activity)
assert Enum.member?(activities, activity_one)
- activities = ActivityPub.fetch_activities([], %{"muting_user" => nil})
+ activities = ActivityPub.fetch_activities([], %{"muting_user" => nil, "skip_preload" => true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@@ -353,6 +398,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert Enum.member?(activities, activity_one)
end
+ test "does include announces on request" do
+ activity_three = insert(:note_activity)
+ user = insert(:user)
+ booster = insert(:user)
+
+ {:ok, user} = User.follow(user, booster)
+
+ {:ok, announce, _object} = CommonAPI.repeat(activity_three.id, booster)
+
+ [announce_activity] = ActivityPub.fetch_activities([user.ap_id | user.following])
+
+ assert announce_activity.id == announce.id
+ end
+
test "excludes reblogs on request" do
user = insert(:user)
{:ok, expected_activity} = ActivityBuilder.insert(%{"type" => "Create"}, %{:user => user})
@@ -435,7 +494,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
- refute Enum.member?(activities, activity)
+ refute Enum.any?(activities, fn %{id: id} -> id == activity.id end)
+ end
+
+ test "returns reblogs for users for whom reblogs have not been muted" do
+ activity = insert(:note_activity)
+ user = insert(:user)
+ booster = insert(:user)
+ {:ok, user} = CommonAPI.hide_reblogs(user, booster)
+ {:ok, user} = CommonAPI.show_reblogs(user, booster)
+
+ {:ok, activity, _} = CommonAPI.repeat(activity.id, booster)
+
+ activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
+
+ assert Enum.any?(activities, fn %{id: id} -> id == activity.id end)
end
end
@@ -725,6 +798,40 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert user.ap_id in delete.data["to"]
end
+
+ test "decreases reply count" do
+ user = insert(:user)
+ user2 = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "1", "visibility" => "public"})
+ reply_data = %{"status" => "1", "in_reply_to_status_id" => activity.id}
+ ap_id = activity.data["id"]
+
+ {:ok, public_reply} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "public"))
+ {:ok, unlisted_reply} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "unlisted"))
+ {:ok, private_reply} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "private"))
+ {:ok, direct_reply} = CommonAPI.post(user2, Map.put(reply_data, "visibility", "direct"))
+
+ _ = CommonAPI.delete(direct_reply.id, user2)
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 2
+ assert object.data["repliesCount"] == 2
+
+ _ = CommonAPI.delete(private_reply.id, user2)
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 2
+ assert object.data["repliesCount"] == 2
+
+ _ = CommonAPI.delete(public_reply.id, user2)
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 1
+ assert object.data["repliesCount"] == 1
+
+ _ = CommonAPI.delete(unlisted_reply.id, user2)
+ assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
+ assert data["object"]["repliesCount"] == 0
+ assert object.data["repliesCount"] == 0
+ end
end
describe "timeline post-processing" do
@@ -763,6 +870,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activities = ActivityPub.fetch_activities([user1.ap_id | user1.following])
+ private_activity_1 = Activity.get_by_ap_id_with_object(private_activity_1.data["id"])
assert [public_activity, private_activity_1, private_activity_3] == activities
assert length(activities) == 3
diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs
index 0bc1d4728..9fb9455d2 100644
--- a/test/web/activity_pub/views/user_view_test.exs
+++ b/test/web/activity_pub/views/user_view_test.exs
@@ -16,6 +16,29 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
assert String.contains?(result["publicKey"]["publicKeyPem"], "BEGIN PUBLIC KEY")
end
+ test "Does not add an avatar image if the user hasn't set one" do
+ user = insert(:user)
+ {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
+
+ result = UserView.render("user.json", %{user: user})
+ refute result["icon"]
+ refute result["image"]
+
+ user =
+ insert(:user,
+ avatar: %{"url" => [%{"href" => "https://someurl"}]},
+ info: %{
+ banner: %{"url" => [%{"href" => "https://somebanner"}]}
+ }
+ )
+
+ {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
+
+ result = UserView.render("user.json", %{user: user})
+ assert result["icon"]["url"] == "https://someurl"
+ assert result["image"]["url"] == "https://somebanner"
+ end
+
describe "endpoints" do
test "local users have a usable endpoints structure" do
user = insert(:user)
diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs
index 0aab7f262..2f53416a3 100644
--- a/test/web/admin_api/admin_api_controller_test.exs
+++ b/test/web/admin_api/admin_api_controller_test.exs
@@ -40,6 +40,41 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
+ describe "/api/pleroma/admin/users/:nickname" do
+ test "Show", %{conn: conn} do
+ admin = insert(:user, info: %{is_admin: true})
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, admin)
+ |> get("/api/pleroma/admin/users/#{user.nickname}")
+
+ expected = %{
+ "deactivated" => false,
+ "id" => to_string(user.id),
+ "local" => true,
+ "nickname" => user.nickname,
+ "roles" => %{"admin" => false, "moderator" => false},
+ "tags" => []
+ }
+
+ assert expected == json_response(conn, 200)
+ end
+
+ test "when the user doesn't exist", %{conn: conn} do
+ admin = insert(:user, info: %{is_admin: true})
+ user = build(:user)
+
+ conn =
+ conn
+ |> assign(:user, admin)
+ |> get("/api/pleroma/admin/users/#{user.nickname}")
+
+ assert "Not found" == json_response(conn, 404)
+ end
+ end
+
describe "PUT /api/pleroma/admin/users/tag" do
setup do
admin = insert(:user, info: %{is_admin: true})
@@ -408,13 +443,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
test "regular search with page size" do
admin = insert(:user, info: %{is_admin: true})
- user = insert(:user, nickname: "bob")
- user2 = insert(:user, nickname: "bo")
+ user = insert(:user, nickname: "aalice")
+ user2 = insert(:user, nickname: "alice")
conn =
build_conn()
|> assign(:user, admin)
- |> get("/api/pleroma/admin/users?query=bo&page_size=1&page=1")
+ |> get("/api/pleroma/admin/users?query=a&page_size=1&page=1")
assert json_response(conn, 200) == %{
"count" => 2,
@@ -434,7 +469,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
conn =
build_conn()
|> assign(:user, admin)
- |> get("/api/pleroma/admin/users?query=bo&page_size=1&page=2")
+ |> get("/api/pleroma/admin/users?query=a&page_size=1&page=2")
assert json_response(conn, 200) == %{
"count" => 2,
@@ -461,7 +496,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
conn =
build_conn()
|> assign(:user, admin)
- |> get("/api/pleroma/admin/users?query=bo&local_only=true")
+ |> get("/api/pleroma/admin/users?query=bo&filters=local")
assert json_response(conn, 200) == %{
"count" => 1,
@@ -488,7 +523,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
conn =
build_conn()
|> assign(:user, admin)
- |> get("/api/pleroma/admin/users?local_only=true")
+ |> get("/api/pleroma/admin/users?filters=local")
assert json_response(conn, 200) == %{
"count" => 2,
@@ -513,6 +548,34 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
]
}
end
+
+ test "it works with multiple filters" do
+ admin = insert(:user, nickname: "john", info: %{is_admin: true})
+ user = insert(:user, nickname: "bob", local: false, info: %{deactivated: true})
+
+ insert(:user, nickname: "ken", local: true, info: %{deactivated: true})
+ insert(:user, nickname: "bobb", local: false, info: %{deactivated: false})
+
+ conn =
+ build_conn()
+ |> assign(:user, admin)
+ |> get("/api/pleroma/admin/users?filters=deactivated,external")
+
+ assert json_response(conn, 200) == %{
+ "count" => 1,
+ "page_size" => 50,
+ "users" => [
+ %{
+ "deactivated" => user.info.deactivated,
+ "id" => user.id,
+ "nickname" => user.nickname,
+ "roles" => %{"admin" => false, "moderator" => false},
+ "local" => user.local,
+ "tags" => []
+ }
+ ]
+ }
+ end
end
test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
diff --git a/test/web/admin_api/search_test.exs b/test/web/admin_api/search_test.exs
new file mode 100644
index 000000000..3950996ed
--- /dev/null
+++ b/test/web/admin_api/search_test.exs
@@ -0,0 +1,88 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.SearchTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.Web.AdminAPI.Search
+
+ import Pleroma.Factory
+
+ describe "search for admin" do
+ test "it ignores case" do
+ insert(:user, nickname: "papercoach")
+ insert(:user, nickname: "CanadaPaperCoach")
+
+ {:ok, _results, count} =
+ Search.user(%{
+ query: "paper",
+ local: false,
+ page: 1,
+ page_size: 50
+ })
+
+ assert count == 2
+ end
+
+ test "it returns local/external users" do
+ insert(:user, local: true)
+ insert(:user, local: false)
+ insert(:user, local: false)
+
+ {:ok, _results, local_count} =
+ Search.user(%{
+ query: "",
+ local: true
+ })
+
+ {:ok, _results, external_count} =
+ Search.user(%{
+ query: "",
+ external: true
+ })
+
+ assert local_count == 1
+ assert external_count == 2
+ end
+
+ test "it returns active/deactivated users" do
+ insert(:user, info: %{deactivated: true})
+ insert(:user, info: %{deactivated: true})
+ insert(:user, info: %{deactivated: false})
+
+ {:ok, _results, active_count} =
+ Search.user(%{
+ query: "",
+ active: true
+ })
+
+ {:ok, _results, deactivated_count} =
+ Search.user(%{
+ query: "",
+ deactivated: true
+ })
+
+ assert active_count == 1
+ assert deactivated_count == 2
+ end
+
+ test "it returns specific user" do
+ insert(:user)
+ insert(:user)
+ insert(:user, nickname: "bob", local: true, info: %{deactivated: false})
+
+ {:ok, _results, total_count} = Search.user(%{query: ""})
+
+ {:ok, _results, count} =
+ Search.user(%{
+ query: "Bo",
+ active: true,
+ local: true
+ })
+
+ assert total_count == 3
+ assert count == 1
+ end
+ end
+end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index b2302422b..d9bcbf5a9 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -14,7 +14,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.FilterView
+ alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OStatus
+ alias Pleroma.Web.Push
alias Pleroma.Web.TwitterAPI.TwitterAPI
import Pleroma.Factory
import ExUnit.CaptureLog
@@ -332,6 +334,53 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert id == to_string(user.id)
end
+ test "apps/verify_credentials", %{conn: conn} do
+ token = insert(:oauth_token)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> get("/api/v1/apps/verify_credentials")
+
+ app = Repo.preload(token, :app).app
+
+ expected = %{
+ "name" => app.client_name,
+ "website" => app.website,
+ "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
+ }
+
+ assert expected == json_response(conn, 200)
+ end
+
+ test "creates an oauth app", %{conn: conn} do
+ user = insert(:user)
+ app_attrs = build(:oauth_app)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/apps", %{
+ client_name: app_attrs.client_name,
+ redirect_uris: app_attrs.redirect_uris
+ })
+
+ [app] = Repo.all(App)
+
+ expected = %{
+ "name" => app.client_name,
+ "website" => app.website,
+ "client_id" => app.client_id,
+ "client_secret" => app.client_secret,
+ "id" => app.id |> to_string(),
+ "redirect_uri" => app.redirect_uris,
+ "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key)
+ }
+
+ assert expected == json_response(conn, 200)
+ end
+
test "get a status", %{conn: conn} do
activity = insert(:note_activity)
@@ -1808,6 +1857,27 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end
test "get instance information", %{conn: conn} do
+ conn = get(conn, "/api/v1/instance")
+ assert result = json_response(conn, 200)
+
+ # Note: not checking for "max_toot_chars" since it's optional
+ assert %{
+ "uri" => _,
+ "title" => _,
+ "description" => _,
+ "version" => _,
+ "email" => _,
+ "urls" => %{
+ "streaming_api" => _
+ },
+ "stats" => _,
+ "thumbnail" => _,
+ "languages" => _,
+ "registrations" => _
+ } = result
+ end
+
+ test "get instance stats", %{conn: conn} do
user = insert(:user, %{local: true})
user2 = insert(:user, %{local: true})
diff --git a/test/web/oauth/ldap_authorization_test.exs b/test/web/oauth/ldap_authorization_test.exs
index 5bf7eb93c..0eb191c76 100644
--- a/test/web/oauth/ldap_authorization_test.exs
+++ b/test/web/oauth/ldap_authorization_test.exs
@@ -10,6 +10,8 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
import ExUnit.CaptureLog
import Mock
+ @skip if !Code.ensure_loaded?(:eldap), do: :skip
+
setup_all do
ldap_authenticator =
Pleroma.Config.get(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.PleromaAuthenticator)
@@ -27,6 +29,7 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
:ok
end
+ @tag @skip
test "authorizes the existing user using LDAP credentials" do
password = "testpassword"
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
@@ -65,6 +68,7 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
end
end
+ @tag @skip
test "creates a new user after successful LDAP authorization" do
password = "testpassword"
user = build(:user)
@@ -110,6 +114,7 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
end
end
+ @tag @skip
test "falls back to the default authorization when LDAP is unavailable" do
password = "testpassword"
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
@@ -153,6 +158,7 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
end
end
+ @tag @skip
test "disallow authorization for wrong LDAP credentials" do
password = "testpassword"
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs
index ff1e56fe9..84ec7b4ee 100644
--- a/test/web/oauth/oauth_controller_test.exs
+++ b/test/web/oauth/oauth_controller_test.exs
@@ -87,7 +87,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
assert result =~ app.redirect_uris
# Error message
- assert result =~ "Permissions not specified"
+ assert result =~ "This action is outside the authorized scopes"
end
test "returns 401 for scopes beyond app scopes", %{conn: conn} do
@@ -113,7 +113,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
assert result =~ app.redirect_uris
# Error message
- assert result =~ "Permissions not specified"
+ assert result =~ "This action is outside the authorized scopes"
end
test "issues a token for an all-body request" do
diff --git a/test/web/twitter_api/representers/activity_representer_test.exs b/test/web/twitter_api/representers/activity_representer_test.exs
deleted file mode 100644
index d154385a0..000000000
--- a/test/web/twitter_api/representers/activity_representer_test.exs
+++ /dev/null
@@ -1,170 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
- use Pleroma.DataCase
- alias Pleroma.Activity
- alias Pleroma.Object
- alias Pleroma.User
- alias Pleroma.Web.ActivityPub.ActivityPub
- alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
- alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
- alias Pleroma.Web.TwitterAPI.UserView
- import Pleroma.Factory
-
- test "a like activity" do
- user = insert(:user)
- note_activity = insert(:note_activity)
- object = Object.get_by_ap_id(note_activity.data["object"]["id"])
-
- {:ok, like_activity, _object} = ActivityPub.like(user, object)
-
- status =
- ActivityRepresenter.to_map(like_activity, %{user: user, liked_activity: note_activity})
-
- assert status["id"] == like_activity.id
- assert status["in_reply_to_status_id"] == note_activity.id
-
- note_activity = Activity.get_by_ap_id(note_activity.data["id"])
- activity_actor = Repo.get_by(User, ap_id: note_activity.data["actor"])
- liked_status = ActivityRepresenter.to_map(note_activity, %{user: activity_actor, for: user})
- assert liked_status["favorited"] == true
- assert status["activity_type"] == "like"
- end
-
- test "an activity" do
- user = insert(:user)
- # {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
- mentioned_user = insert(:user, %{nickname: "shp"})
-
- # {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
- follower = insert(:user, %{following: [User.ap_followers(user)]})
-
- object = %Object{
- data: %{
- "type" => "Image",
- "url" => [
- %{
- "type" => "Link",
- "mediaType" => "image/jpg",
- "href" => "http://example.org/image.jpg"
- }
- ],
- "uuid" => 1
- }
- }
-
- content_html =
- "<script>alert('YAY')</script>Some :2hu: content mentioning <a href='#{mentioned_user.ap_id}'>@shp</shp>"
-
- content = HtmlSanitizeEx.strip_tags(content_html)
- date = DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC") |> DateTime.to_iso8601()
-
- {:ok, convo_object} = Object.context_mapping("2hu") |> Repo.insert()
-
- to = [
- User.ap_followers(user),
- "https://www.w3.org/ns/activitystreams#Public",
- mentioned_user.ap_id
- ]
-
- activity = %Activity{
- id: 1,
- data: %{
- "type" => "Create",
- "id" => "id",
- "to" => to,
- "actor" => User.ap_id(user),
- "object" => %{
- "published" => date,
- "type" => "Note",
- "content" => content_html,
- "summary" => "2hu :2hu:",
- "inReplyToStatusId" => 213_123,
- "attachment" => [
- object
- ],
- "external_url" => "some url",
- "like_count" => 5,
- "announcement_count" => 3,
- "context" => "2hu",
- "tag" => ["content", "mentioning", "nsfw"],
- "emoji" => %{
- "2hu" => "corndog.png"
- }
- },
- "published" => date,
- "context" => "2hu"
- },
- local: false,
- recipients: to
- }
-
- corndog_emojo = ~s(<img height="32px" width="32px" alt="2hu" title="2hu" src="corndog.png" />)
-
- expected_html =
- ~s(<p>2hu ) <>
- corndog_emojo <>
- ~s(</p>alert\('YAY'\)Some ) <>
- corndog_emojo <>
- ~s( content mentioning <a href=") <> mentioned_user.ap_id <> ~s(">@shp</a>)
-
- expected_status = %{
- "id" => activity.id,
- "user" => UserView.render("show.json", %{user: user, for: follower}),
- "is_local" => false,
- "statusnet_html" => expected_html,
- "text" => "2hu :2hu:" <> content,
- "is_post_verb" => true,
- "created_at" => "Tue May 24 13:26:08 +0000 2016",
- "in_reply_to_status_id" => 213_123,
- "in_reply_to_screen_name" => nil,
- "in_reply_to_user_id" => nil,
- "in_reply_to_profileurl" => nil,
- "in_reply_to_ostatus_uri" => nil,
- "statusnet_conversation_id" => convo_object.id,
- "attachments" => [
- ObjectRepresenter.to_map(object)
- ],
- "attentions" => [
- UserView.render("show.json", %{user: mentioned_user, for: follower})
- ],
- "fave_num" => 5,
- "repeat_num" => 3,
- "favorited" => false,
- "repeated" => false,
- "pinned" => false,
- "external_url" => "some url",
- "tags" => ["nsfw", "content", "mentioning"],
- "activity_type" => "post",
- "possibly_sensitive" => true,
- "uri" => activity.data["object"]["id"],
- "visibility" => "direct",
- "card" => nil,
- "muted" => false,
- "summary" => "2hu :2hu:",
- "summary_html" =>
- "2hu <img height=\"32px\" width=\"32px\" alt=\"2hu\" title=\"2hu\" src=\"corndog.png\" />"
- }
-
- assert ActivityRepresenter.to_map(activity, %{
- user: user,
- for: follower,
- mentioned: [mentioned_user]
- }) == expected_status
- end
-
- test "a delete activity" do
- object = insert(:note)
- user = User.get_by_ap_id(object.data["actor"])
-
- {:ok, delete} = ActivityPub.delete(object)
-
- map = ActivityRepresenter.to_map(delete, %{user: user})
-
- assert map["is_post_verb"] == false
- assert map["activity_type"] == "delete"
- assert map["uri"] == object.data["id"]
- end
-end
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs
index 1b810c9a0..083540017 100644
--- a/test/web/twitter_api/twitter_api_controller_test.exs
+++ b/test/web/twitter_api/twitter_api_controller_test.exs
@@ -16,9 +16,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth.Token
+ alias Pleroma.Web.TwitterAPI.ActivityView
alias Pleroma.Web.TwitterAPI.Controller
alias Pleroma.Web.TwitterAPI.NotificationView
- alias Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter
alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.UserView
@@ -116,7 +116,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|> post(request_path, %{status: "Nice meme.", visibility: "private"})
assert json_response(conn, 200) ==
- ActivityRepresenter.to_map(Repo.one(Activity), %{user: user, for: user})
+ ActivityView.render("activity.json", %{
+ activity: Repo.one(Activity),
+ user: user,
+ for: user
+ })
end
end
@@ -273,7 +277,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200)
- assert response == ActivityRepresenter.to_map(activity, %{user: actor})
+ assert response == ActivityView.render("activity.json", %{activity: activity, user: actor})
end
end
@@ -372,7 +376,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert response ==
Enum.map(returned_activities, fn activity ->
- ActivityRepresenter.to_map(activity, %{
+ ActivityView.render("activity.json", %{
+ activity: activity,
user: User.get_cached_by_ap_id(activity.data["actor"]),
for: current_user
})
@@ -469,10 +474,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert length(response) == 1
assert Enum.at(response, 0) ==
- ActivityRepresenter.to_map(activity, %{
+ ActivityView.render("activity.json", %{
user: current_user,
for: current_user,
- mentioned: [current_user]
+ activity: activity
})
end
@@ -594,7 +599,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
conn = get(conn, "/api/statuses/user_timeline.json", %{"user_id" => user.id})
response = json_response(conn, 200)
assert length(response) == 1
- assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+ assert Enum.at(response, 0) ==
+ ActivityView.render("activity.json", %{user: user, activity: activity})
end
test "with screen_name", %{conn: conn} do
@@ -604,7 +611,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
conn = get(conn, "/api/statuses/user_timeline.json", %{"screen_name" => user.nickname})
response = json_response(conn, 200)
assert length(response) == 1
- assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+ assert Enum.at(response, 0) ==
+ ActivityView.render("activity.json", %{user: user, activity: activity})
end
test "with credentials", %{conn: conn, user: current_user} do
@@ -620,7 +629,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert length(response) == 1
assert Enum.at(response, 0) ==
- ActivityRepresenter.to_map(activity, %{user: current_user, for: current_user})
+ ActivityView.render("activity.json", %{
+ user: current_user,
+ for: current_user,
+ activity: activity
+ })
end
test "with credentials with user_id", %{conn: conn, user: current_user} do
@@ -635,7 +648,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200)
assert length(response) == 1
- assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+ assert Enum.at(response, 0) ==
+ ActivityView.render("activity.json", %{user: user, activity: activity})
end
test "with credentials screen_name", %{conn: conn, user: current_user} do
@@ -650,7 +665,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200)
assert length(response) == 1
- assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+ assert Enum.at(response, 0) ==
+ ActivityView.render("activity.json", %{user: user, activity: activity})
end
test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
@@ -669,7 +686,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200)
assert length(response) == 1
- assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+ assert Enum.at(response, 0) ==
+ ActivityView.render("activity.json", %{user: user, activity: activity})
conn =
conn
@@ -678,7 +697,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200)
assert length(response) == 1
- assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+ assert Enum.at(response, 0) ==
+ ActivityView.render("activity.json", %{user: user, activity: activity})
end
end
@@ -937,7 +958,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
assert json_response(response, 200) ==
- ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
+ ActivityView.render("activity.json", %{
+ user: activity_user,
+ for: current_user,
+ activity: activity
+ })
end
end
@@ -971,7 +996,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
assert json_response(response, 200) ==
- ActivityRepresenter.to_map(activity, %{user: activity_user, for: current_user})
+ ActivityView.render("activity.json", %{
+ user: activity_user,
+ for: current_user,
+ activity: activity
+ })
end
end
@@ -1955,7 +1984,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
user = refresh_record(user)
assert json_response(response, 200) ==
- ActivityRepresenter.to_map(activity, %{user: user, for: user})
+ ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
end
end
@@ -1985,7 +2014,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
user = refresh_record(user)
assert json_response(response, 200) ==
- ActivityRepresenter.to_map(activity, %{user: user, for: user})
+ ActivityView.render("activity.json", %{user: user, for: user, activity: activity})
end
end