aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/web
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web')
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex35
-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/federator/federator.ex19
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex25
-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/router.ex2
-rw-r--r--lib/pleroma/web/twitter_api/representers/activity_representer.ex15
11 files changed, 219 insertions, 60 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 80c64ae04..6e1ed7ec9 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -89,6 +89,30 @@ 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),
@@ -178,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),
@@ -329,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),
@@ -711,8 +737,13 @@ 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
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/federator/federator.ex b/lib/pleroma/web/federator/federator.ex
index 5e690ddb8..c47328e13 100644
--- a/lib/pleroma/web/federator/federator.ex
+++ b/lib/pleroma/web/federator/federator.ex
@@ -4,7 +4,6 @@
defmodule Pleroma.Web.Federator do
alias Pleroma.Activity
- alias Pleroma.Jobs
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay
@@ -31,39 +30,39 @@ defmodule Pleroma.Web.Federator do
# Client API
def incoming_doc(doc) do
- Jobs.enqueue(:federator_incoming, __MODULE__, [:incoming_doc, doc])
+ PleromaJobQueue.enqueue(:federator_incoming, __MODULE__, [:incoming_doc, doc])
end
def incoming_ap_doc(params) do
- Jobs.enqueue(:federator_incoming, __MODULE__, [:incoming_ap_doc, params])
+ PleromaJobQueue.enqueue(:federator_incoming, __MODULE__, [:incoming_ap_doc, params])
end
def publish(activity, priority \\ 1) do
- Jobs.enqueue(:federator_outgoing, __MODULE__, [:publish, activity], priority)
+ PleromaJobQueue.enqueue(:federator_outgoing, __MODULE__, [:publish, activity], priority)
end
def publish_single_ap(params) do
- Jobs.enqueue(:federator_outgoing, __MODULE__, [:publish_single_ap, params])
+ PleromaJobQueue.enqueue(:federator_outgoing, __MODULE__, [:publish_single_ap, params])
end
def publish_single_websub(websub) do
- Jobs.enqueue(:federator_outgoing, __MODULE__, [:publish_single_websub, websub])
+ PleromaJobQueue.enqueue(:federator_outgoing, __MODULE__, [:publish_single_websub, websub])
end
def verify_websub(websub) do
- Jobs.enqueue(:federator_outgoing, __MODULE__, [:verify_websub, websub])
+ PleromaJobQueue.enqueue(:federator_outgoing, __MODULE__, [:verify_websub, websub])
end
def request_subscription(sub) do
- Jobs.enqueue(:federator_outgoing, __MODULE__, [:request_subscription, sub])
+ PleromaJobQueue.enqueue(:federator_outgoing, __MODULE__, [:request_subscription, sub])
end
def refresh_subscriptions do
- Jobs.enqueue(:federator_outgoing, __MODULE__, [:refresh_subscriptions])
+ PleromaJobQueue.enqueue(:federator_outgoing, __MODULE__, [:refresh_subscriptions])
end
def publish_single_salmon(params) do
- Jobs.enqueue(:federator_outgoing, __MODULE__, [:publish_single_salmon, params])
+ PleromaJobQueue.enqueue(:federator_outgoing, __MODULE__, [:publish_single_salmon, params])
end
# Job Worker Callbacks
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 6be0f2baf..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)
}
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 078839d5c..e54e196aa 100644
--- a/lib/pleroma/web/oauth/oauth_controller.ex
+++ b/lib/pleroma/web/oauth/oauth_controller.ex
@@ -74,14 +74,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)
@@ -140,9 +144,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/router.ex b/lib/pleroma/web/router.ex
index 4d0e04d9f..8a157e223 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -145,6 +145,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)
@@ -343,6 +344,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/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