summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIvan Tashkinov <ivantashkinov@gmail.com>2021-02-03 09:31:38 +0300
committerIvan Tashkinov <ivantashkinov@gmail.com>2021-02-03 09:31:38 +0300
commit4e14945670bac15a6e183eb8c552d6e0669713ac (patch)
treec25db5253cafb81dbfa31cc779ffae8e07806b7e /lib
parentcf4765af4098098fa4d6996193432bd19c439a75 (diff)
parentfd2477dfba1f167c7519a029bedd7ae6884a9f1d (diff)
downloadpleroma-4e14945670bac15a6e183eb8c552d6e0669713ac.tar.gz
pleroma-4e14945670bac15a6e183eb8c552d6e0669713ac.zip
Merge remote-tracking branch 'remotes/origin/develop' into feature/object-hashtags-rework
# Conflicts: # CHANGELOG.md # lib/pleroma/web/activity_pub/activity_pub.ex
Diffstat (limited to 'lib')
-rw-r--r--lib/mix/tasks/pleroma/instance.ex11
-rw-r--r--lib/pleroma/user.ex25
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex7
-rw-r--r--lib/pleroma/web/api_spec/operations/account_operation.ex11
-rw-r--r--lib/pleroma/web/api_spec/operations/timeline_operation.ex16
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex15
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex3
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex4
-rw-r--r--lib/pleroma/web/mastodon_api/views/instance_view.ex1
-rw-r--r--lib/pleroma/web/plugs/user_tracking_plug.ex30
-rw-r--r--lib/pleroma/web/router.ex3
-rw-r--r--lib/pleroma/web/templates/embed/show.html.eex2
-rw-r--r--lib/pleroma/web/views/embed_view.ex7
-rw-r--r--lib/pleroma/workers/attachments_cleanup_worker.ex14
-rw-r--r--lib/pleroma/workers/purge_expired_activity.ex2
15 files changed, 126 insertions, 25 deletions
diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex
index f272fdb7f..da27a99d0 100644
--- a/lib/mix/tasks/pleroma/instance.ex
+++ b/lib/mix/tasks/pleroma/instance.ex
@@ -242,6 +242,13 @@ defmodule Mix.Tasks.Pleroma.Instance do
rum_enabled: rum_enabled
)
+ config_dir = Path.dirname(config_path)
+ psql_dir = Path.dirname(psql_path)
+
+ [config_dir, psql_dir, static_dir, uploads_dir]
+ |> Enum.reject(&File.exists?/1)
+ |> Enum.map(&File.mkdir_p!/1)
+
shell_info("Writing config to #{config_path}.")
File.write(config_path, result_config)
@@ -275,10 +282,6 @@ defmodule Mix.Tasks.Pleroma.Instance do
indexable: indexable
)
- unless File.exists?(static_dir) do
- File.mkdir_p!(static_dir)
- end
-
robots_txt_path = Path.join(static_dir, "robots.txt")
if File.exists?(robots_txt_path) do
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index e422b59f1..b69709db4 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -146,6 +146,7 @@ defmodule Pleroma.User do
field(:inbox, :string)
field(:shared_inbox, :string)
field(:accepts_chat_messages, :boolean, default: nil)
+ field(:last_active_at, :naive_datetime)
embeds_one(
:notification_settings,
@@ -2030,6 +2031,15 @@ defmodule Pleroma.User do
|> hd()
end
+ def full_nickname(%User{} = user) do
+ if String.contains?(user.nickname, "@") do
+ user.nickname
+ else
+ %{host: host} = URI.parse(user.ap_id)
+ user.nickname <> "@" <> host
+ end
+ end
+
def full_nickname(nickname_or_mention),
do: String.trim_leading(nickname_or_mention, "@")
@@ -2444,4 +2454,19 @@ defmodule Pleroma.User do
def get_host(%User{ap_id: ap_id} = _user) do
URI.parse(ap_id).host
end
+
+ def update_last_active_at(%__MODULE__{local: true} = user) do
+ user
+ |> cast(%{last_active_at: NaiveDateTime.utc_now()}, [:last_active_at])
+ |> update_and_set_cache()
+ end
+
+ def active_user_count(weeks \\ 4) do
+ active_after = Timex.shift(NaiveDateTime.utc_now(), weeks: -weeks)
+
+ __MODULE__
+ |> where([u], u.last_active_at >= ^active_after)
+ |> where([u], u.local == true)
+ |> Repo.aggregate(:count)
+ end
end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 6cf4093fb..573b4243c 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -824,6 +824,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_local(query, _), do: query
+ defp restrict_remote(query, %{remote: true}) do
+ from(activity in query, where: activity.local == false)
+ end
+
+ defp restrict_remote(query, _), do: query
+
defp restrict_actor(query, %{actor_id: actor_id}) do
from(activity in query, where: activity.actor == ^actor_id)
end
@@ -1198,6 +1204,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> restrict_replies(opts)
|> restrict_since(opts)
|> restrict_local(opts)
+ |> restrict_remote(opts)
|> restrict_actor(opts)
|> restrict_type(opts)
|> restrict_state(opts)
diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex
index 80acee2f7..3d451cd5a 100644
--- a/lib/pleroma/web/api_spec/operations/account_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/account_operation.ex
@@ -99,7 +99,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
summary: "Account",
operationId: "AccountController.show",
description: "View information about a profile.",
- parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
+ parameters: [
+ %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
+ with_relationships_param()
+ ],
responses: %{
200 => Operation.response("Account", "application/json", Account),
401 => Operation.response("Error", "application/json", ApiError),
@@ -130,7 +133,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:with_muted,
:query,
BooleanLike,
- "Include statuses from muted acccounts."
+ "Include statuses from muted accounts."
),
Operation.parameter(:exclude_reblogs, :query, BooleanLike, "Exclude reblogs"),
Operation.parameter(:exclude_replies, :query, BooleanLike, "Exclude replies"),
@@ -144,7 +147,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:with_muted,
:query,
BooleanLike,
- "Include reactions from muted acccounts."
+ "Include reactions from muted accounts."
)
] ++ pagination_params(),
responses: %{
@@ -347,7 +350,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
operationId: "AccountController.mutes",
description: "Accounts the user has muted.",
security: [%{"oAuth" => ["follow", "read:mutes"]}],
- parameters: pagination_params(),
+ parameters: [with_relationships_param() | pagination_params()],
responses: %{
200 => Operation.response("Accounts", "application/json", array_of_accounts())
}
diff --git a/lib/pleroma/web/api_spec/operations/timeline_operation.ex b/lib/pleroma/web/api_spec/operations/timeline_operation.ex
index e1ebdab38..01396642c 100644
--- a/lib/pleroma/web/api_spec/operations/timeline_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/timeline_operation.ex
@@ -25,6 +25,8 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
security: [%{"oAuth" => ["read:statuses"]}],
parameters: [
local_param(),
+ remote_param(),
+ only_media_param(),
with_muted_param(),
exclude_visibilities_param(),
reply_visibility_param() | pagination_params()
@@ -61,6 +63,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
local_param(),
instance_param(),
only_media_param(),
+ remote_param(),
with_muted_param(),
exclude_visibilities_param(),
reply_visibility_param() | pagination_params()
@@ -107,6 +110,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
),
local_param(),
only_media_param(),
+ remote_param(),
with_muted_param(),
exclude_visibilities_param() | pagination_params()
],
@@ -132,6 +136,9 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
required: true
),
with_muted_param(),
+ local_param(),
+ remote_param(),
+ only_media_param(),
exclude_visibilities_param() | pagination_params()
],
operationId: "TimelineController.list",
@@ -198,4 +205,13 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
"Show only statuses with media attached?"
)
end
+
+ defp remote_param do
+ Operation.parameter(
+ :remote,
+ :query,
+ %Schema{allOf: [BooleanLike], default: false},
+ "Show only remote statuses?"
+ )
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index d277aeca5..7a1e99044 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -269,10 +269,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
def relationships(%{assigns: %{user: _user}} = conn, _), do: json(conn, [])
@doc "GET /api/v1/accounts/:id"
- def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id}) do
+ def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id} = params) do
with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user),
:visible <- User.visible_for(user, for_user) do
- render(conn, "show.json", user: user, for: for_user)
+ render(conn, "show.json",
+ user: user,
+ for: for_user,
+ embed_relationships: embed_relationships?(params)
+ )
else
error -> user_visibility_error(conn, error)
end
@@ -454,7 +458,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
conn
|> add_link_headers(users)
- |> render("index.json", users: users, for: user, as: :user)
+ |> render("index.json",
+ users: users,
+ for: user,
+ as: :user,
+ embed_relationships: embed_relationships?(params)
+ )
end
@doc "GET /api/v1/blocks"
diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
index 1fb954a9b..87effa00b 100644
--- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
@@ -51,6 +51,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:reply_filtering_user, user)
|> Map.put(:announce_filtering_user, user)
|> Map.put(:user, user)
+ |> Map.put(:local_only, params[:local])
+ |> Map.delete(:local)
activities =
[user.ap_id | User.following(user)]
@@ -190,6 +192,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:blocking_user, user)
|> Map.put(:user, user)
|> Map.put(:muting_user, user)
+ |> Map.put(:local_only, params[:local])
# we must filter the following list for the user to avoid leaking statuses the user
# does not actually have permission to see (for more info, peruse security issue #270).
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 63417142f..ac25aefdd 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -262,7 +262,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
}
},
- # Pleroma extension
+ # Pleroma extensions
+ # Note: it's insecure to output :email but fully-qualified nickname may serve as safe stub
+ fqn: User.full_nickname(user),
pleroma: %{
ap_id: user.ap_id,
also_known_as: user.also_known_as,
diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex
index 1edbdbe11..73205fb6d 100644
--- a/lib/pleroma/web/mastodon_api/views/instance_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex
@@ -45,6 +45,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
fields_limits: fields_limits(),
post_formats: Config.get([:instance, :allowed_post_formats])
},
+ stats: %{mau: Pleroma.User.active_user_count()},
vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
}
}
diff --git a/lib/pleroma/web/plugs/user_tracking_plug.ex b/lib/pleroma/web/plugs/user_tracking_plug.ex
new file mode 100644
index 000000000..c9a988f00
--- /dev/null
+++ b/lib/pleroma/web/plugs/user_tracking_plug.ex
@@ -0,0 +1,30 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.Plugs.UserTrackingPlug do
+ alias Pleroma.User
+
+ import Plug.Conn, only: [assign: 3]
+
+ @update_interval :timer.hours(24)
+
+ def init(opts), do: opts
+
+ def call(%{assigns: %{user: %User{id: id} = user}} = conn, _) when not is_nil(id) do
+ with true <- needs_update?(user),
+ {:ok, user} <- User.update_last_active_at(user) do
+ assign(conn, :user, user)
+ else
+ _ -> conn
+ end
+ end
+
+ def call(conn, _), do: conn
+
+ defp needs_update?(%User{last_active_at: nil}), do: true
+
+ defp needs_update?(%User{last_active_at: last_active_at}) do
+ NaiveDateTime.diff(NaiveDateTime.utc_now(), last_active_at, :millisecond) >= @update_interval
+ end
+end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index a9e332fa1..2105d7e9e 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -56,6 +56,7 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.UserEnabledPlug)
plug(Pleroma.Web.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Web.Plugs.EnsureUserTokenAssignsPlug)
+ plug(Pleroma.Web.Plugs.UserTrackingPlug)
end
pipeline :base_api do
@@ -319,6 +320,8 @@ defmodule Pleroma.Web.Router do
end
scope "/oauth", Pleroma.Web.OAuth do
+ # Note: use /api/v1/accounts/verify_credentials for userinfo of signed-in user
+
get("/registration_details", OAuthController, :registration_details)
post("/mfa/verify", MFAController, :verify, as: :mfa_verify)
diff --git a/lib/pleroma/web/templates/embed/show.html.eex b/lib/pleroma/web/templates/embed/show.html.eex
index 05a3f0ee3..092b52b70 100644
--- a/lib/pleroma/web/templates/embed/show.html.eex
+++ b/lib/pleroma/web/templates/embed/show.html.eex
@@ -6,7 +6,7 @@
</div>
<span class="display-name" style="padding-left: 0.5em;">
<bdi><%= raw (@author.name |> Formatter.emojify(@author.emoji)) %></bdi>
- <span class="nickname"><%= full_nickname(@author) %></span>
+ <span class="nickname">@<%= full_nickname(@author) %></span>
</span>
</a>
</div>
diff --git a/lib/pleroma/web/views/embed_view.ex b/lib/pleroma/web/views/embed_view.ex
index cb7600adb..81e196730 100644
--- a/lib/pleroma/web/views/embed_view.ex
+++ b/lib/pleroma/web/views/embed_view.ex
@@ -17,6 +17,8 @@ defmodule Pleroma.Web.EmbedView do
use Phoenix.HTML
+ defdelegate full_nickname(user), to: User
+
@media_types ["image", "audio", "video"]
defp fetch_media_type(%{"mediaType" => mediaType}) do
@@ -30,11 +32,6 @@ defmodule Pleroma.Web.EmbedView do
)
end
- defp full_nickname(user) do
- %{host: host} = URI.parse(user.ap_id)
- "@" <> user.nickname <> "@" <> host
- end
-
defp status_title(%Activity{object: %Object{data: %{"name" => name}}}) when is_binary(name),
do: name
diff --git a/lib/pleroma/workers/attachments_cleanup_worker.ex b/lib/pleroma/workers/attachments_cleanup_worker.ex
index a2373ebb9..f5090dae7 100644
--- a/lib/pleroma/workers/attachments_cleanup_worker.ex
+++ b/lib/pleroma/workers/attachments_cleanup_worker.ex
@@ -17,12 +17,14 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do
"object" => %{"data" => %{"attachment" => [_ | _] = attachments, "actor" => actor}}
}
}) do
- attachments
- |> Enum.flat_map(fn item -> Enum.map(item["url"], & &1["href"]) end)
- |> fetch_objects
- |> prepare_objects(actor, Enum.map(attachments, & &1["name"]))
- |> filter_objects
- |> do_clean
+ if Pleroma.Config.get([:instance, :cleanup_attachments], false) do
+ attachments
+ |> Enum.flat_map(fn item -> Enum.map(item["url"], & &1["href"]) end)
+ |> fetch_objects
+ |> prepare_objects(actor, Enum.map(attachments, & &1["name"]))
+ |> filter_objects
+ |> do_clean
+ end
{:ok, :success}
end
diff --git a/lib/pleroma/workers/purge_expired_activity.ex b/lib/pleroma/workers/purge_expired_activity.ex
index 01256831b..027171c1e 100644
--- a/lib/pleroma/workers/purge_expired_activity.ex
+++ b/lib/pleroma/workers/purge_expired_activity.ex
@@ -7,7 +7,7 @@ defmodule Pleroma.Workers.PurgeExpiredActivity do
Worker which purges expired activity.
"""
- use Oban.Worker, queue: :activity_expiration, max_attempts: 1
+ use Oban.Worker, queue: :activity_expiration, max_attempts: 1, unique: [period: :infinity]
import Ecto.Query