aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--config/config.exs3
-rw-r--r--docs/API/differences_in_mastoapi_responses.md4
-rw-r--r--docs/administration/CLI_tasks/release_environments.md9
-rw-r--r--docs/installation/debian_based_en.md1
-rw-r--r--docs/installation/otp_en.md3
-rwxr-xr-xinstallation/init.d/pleroma1
-rw-r--r--installation/pleroma.service2
-rw-r--r--lib/mix/tasks/pleroma/instance.ex22
-rw-r--r--lib/mix/tasks/pleroma/release_env.ex76
-rw-r--r--lib/pleroma/stats.ex19
-rw-r--r--lib/pleroma/user.ex59
-rw-r--r--lib/pleroma/web/api_spec/operations/account_operation.ex15
-rw-r--r--lib/pleroma/web/api_spec/operations/status_operation.ex22
-rw-r--r--lib/pleroma/web/common_api.ex30
-rw-r--r--lib/pleroma/web/fallback/redirect_controller.ex4
-rw-r--r--lib/pleroma/web/feed/feed_view.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/account_controller.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/status_controller.ex4
-rw-r--r--lib/pleroma/web/templates/feed/feed/_activity.atom.eex2
-rw-r--r--lib/pleroma/web/templates/feed/feed/_activity.rss.eex2
-rw-r--r--lib/pleroma/workers/mute_expire_worker.ex20
-rw-r--r--test/mix/tasks/pleroma/instance_test.exs11
-rw-r--r--test/mix/tasks/pleroma/release_env_test.exs30
-rw-r--r--test/pleroma/notification_test.exs4
-rw-r--r--test/pleroma/user_test.exs34
-rw-r--r--test/pleroma/web/common_api_test.exs24
-rw-r--r--test/pleroma/web/feed/user_controller_test.exs77
-rw-r--r--test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs2
-rw-r--r--test/pleroma/web/mastodon_api/views/account_view_test.exs2
30 files changed, 231 insertions, 256 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 756939dde..b15ddb943 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Admin API: (`GET /api/pleroma/admin/users`) added filters user by `actor_type`
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
+- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
</details>
diff --git a/config/config.exs b/config/config.exs
index ed7bda9ee..0b8a75aad 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -562,7 +562,8 @@ config :pleroma, Oban,
background: 5,
remote_fetcher: 2,
attachments_cleanup: 5,
- new_users_digest: 1
+ new_users_digest: 1,
+ mute_expire: 5
],
plugins: [Oban.Plugins.Pruner],
crontab: [
diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md
index bb1000b0b..3075b6b86 100644
--- a/docs/API/differences_in_mastoapi_responses.md
+++ b/docs/API/differences_in_mastoapi_responses.md
@@ -255,6 +255,10 @@ There is an additional `user:pleroma_chat` stream. Incoming chat messages will m
For viewing remote server timelines, there are `public:remote` and `public:remote:media` streams. Each of these accept a parameter like `?instance=lain.com`.
+## User muting and thread muting
+
+Both user muting and thread muting can be done for only a certain time by adding an `expires_in` parameter to the API calls and giving the expiration time in seconds.
+
## Not implemented
Pleroma is generally compatible with the Mastodon 2.7.2 API, but some newer features and non-essential features are omitted. These features usually return an HTTP 200 status code, but with an empty response. While they may be added in the future, they are considered low priority.
diff --git a/docs/administration/CLI_tasks/release_environments.md b/docs/administration/CLI_tasks/release_environments.md
deleted file mode 100644
index 36ab43864..000000000
--- a/docs/administration/CLI_tasks/release_environments.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Generate release environment file
-
-```sh tab="OTP"
- ./bin/pleroma_ctl release_env gen
-```
-
-```sh tab="From Source"
-mix pleroma.release_env gen
-```
diff --git a/docs/installation/debian_based_en.md b/docs/installation/debian_based_en.md
index b9fc4e112..75ceb6595 100644
--- a/docs/installation/debian_based_en.md
+++ b/docs/installation/debian_based_en.md
@@ -182,7 +182,6 @@ sudo cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.se
```
* Edit the service file and make sure that all paths fit your installation
-* Check that `EnvironmentFile` contains the correct path to the env file. Or generate the env file: `sudo -Hu pleroma mix pleroma.release_env gen`
* Enable and start `pleroma.service`:
```shell
diff --git a/docs/installation/otp_en.md b/docs/installation/otp_en.md
index 98360bcf7..63eda63ca 100644
--- a/docs/installation/otp_en.md
+++ b/docs/installation/otp_en.md
@@ -149,9 +149,6 @@ chown -R pleroma /etc/pleroma
# Run the config generator
su pleroma -s $SHELL -lc "./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql"
-# Run the environment file generator.
-su pleroma -s $SHELL -lc "./bin/pleroma_ctl release_env gen"
-
# Create the postgres database
su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"
diff --git a/installation/init.d/pleroma b/installation/init.d/pleroma
index e908cda1b..384536f7e 100755
--- a/installation/init.d/pleroma
+++ b/installation/init.d/pleroma
@@ -8,7 +8,6 @@ pidfile="/var/run/pleroma.pid"
directory=/opt/pleroma
healthcheck_delay=60
healthcheck_timer=30
-export $(cat /opt/pleroma/config/pleroma.env)
: ${pleroma_port:-4000}
diff --git a/installation/pleroma.service b/installation/pleroma.service
index 63e83ed6e..8338228d8 100644
--- a/installation/pleroma.service
+++ b/installation/pleroma.service
@@ -17,8 +17,6 @@ Environment="MIX_ENV=prod"
Environment="HOME=/var/lib/pleroma"
; Path to the folder containing the Pleroma installation.
WorkingDirectory=/opt/pleroma
-; Path to the environment file. the file contains RELEASE_COOKIE and etc
-EnvironmentFile=/opt/pleroma/config/pleroma.env
; Path to the Mix binary.
ExecStart=/usr/bin/mix phx.server
diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex
index 1915aacd9..fc21ae062 100644
--- a/lib/mix/tasks/pleroma/instance.ex
+++ b/lib/mix/tasks/pleroma/instance.ex
@@ -36,9 +36,7 @@ defmodule Mix.Tasks.Pleroma.Instance do
listen_port: :string,
strip_uploads: :string,
anonymize_uploads: :string,
- dedupe_uploads: :string,
- skip_release_env: :boolean,
- release_env_file: :string
+ dedupe_uploads: :string
],
aliases: [
o: :output,
@@ -243,24 +241,6 @@ defmodule Mix.Tasks.Pleroma.Instance do
write_robots_txt(static_dir, indexable, template_dir)
- if Keyword.get(options, :skip_release_env, false) do
- shell_info("""
- Release environment file is skip. Please generate the release env file before start.
- `MIX_ENV=#{Mix.env()} mix pleroma.release_env gen`
- """)
- else
- shell_info("Generation the environment file:")
-
- release_env_args =
- with path when not is_nil(path) <- Keyword.get(options, :release_env_file) do
- ["gen", "--path", path]
- else
- _ -> ["gen"]
- end
-
- Mix.Tasks.Pleroma.ReleaseEnv.run(release_env_args)
- end
-
shell_info(
"\n All files successfully written! Refer to the installation instructions for your platform for next steps."
)
diff --git a/lib/mix/tasks/pleroma/release_env.ex b/lib/mix/tasks/pleroma/release_env.ex
deleted file mode 100644
index 9da74ffcf..000000000
--- a/lib/mix/tasks/pleroma/release_env.ex
+++ /dev/null
@@ -1,76 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Mix.Tasks.Pleroma.ReleaseEnv do
- use Mix.Task
- import Mix.Pleroma
-
- @shortdoc "Generate Pleroma environment file."
- @moduledoc File.read!("docs/administration/CLI_tasks/release_environments.md")
-
- def run(["gen" | rest]) do
- {options, [], []} =
- OptionParser.parse(
- rest,
- strict: [
- force: :boolean,
- path: :string
- ],
- aliases: [
- p: :path,
- f: :force
- ]
- )
-
- file_path =
- get_option(
- options,
- :path,
- "Environment file path",
- "./config/pleroma.env"
- )
-
- env_path = Path.expand(file_path)
-
- proceed? =
- if File.exists?(env_path) do
- get_option(
- options,
- :force,
- "Environment file already exists. Do you want to overwrite the #{env_path} file? (y/n)",
- "n"
- ) === "y"
- else
- true
- end
-
- if proceed? do
- case do_generate(env_path) do
- {:error, reason} ->
- shell_error(
- File.Error.message(%{action: "write to file", reason: reason, path: env_path})
- )
-
- _ ->
- shell_info("\nThe file generated: #{env_path}.\n")
-
- shell_info("""
- WARNING: before start pleroma app please make sure to make the file read-only and non-modifiable.
- Example:
- chmod 0444 #{file_path}
- chattr +i #{file_path}
- """)
- end
- else
- shell_info("\nThe file is exist. #{env_path}.\n")
- end
- end
-
- def do_generate(path) do
- content = "RELEASE_COOKIE=#{Base.encode32(:crypto.strong_rand_bytes(32))}"
-
- File.mkdir_p!(Path.dirname(path))
- File.write(path, content)
- end
-end
diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex
index e5c9c668b..48afe901e 100644
--- a/lib/pleroma/stats.ex
+++ b/lib/pleroma/stats.ex
@@ -23,7 +23,6 @@ defmodule Pleroma.Stats do
@impl true
def init(_args) do
- if Pleroma.Config.get(:env) == :test, do: :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo)
{:ok, nil, {:continue, :calculate_stats}}
end
@@ -32,11 +31,6 @@ defmodule Pleroma.Stats do
GenServer.call(__MODULE__, :force_update)
end
- @doc "Performs collect stats"
- def do_collect do
- GenServer.cast(__MODULE__, :run_update)
- end
-
@doc "Returns stats data"
@spec get_stats() :: %{
domain_count: non_neg_integer(),
@@ -111,7 +105,11 @@ defmodule Pleroma.Stats do
@impl true
def handle_continue(:calculate_stats, _) do
stats = calculate_stat_data()
- Process.send_after(self(), :run_update, @interval)
+
+ unless Pleroma.Config.get(:env) == :test do
+ Process.send_after(self(), :run_update, @interval)
+ end
+
{:noreply, stats}
end
@@ -127,13 +125,6 @@ defmodule Pleroma.Stats do
end
@impl true
- def handle_cast(:run_update, _state) do
- new_stats = calculate_stat_data()
-
- {:noreply, new_stats}
- end
-
- @impl true
def handle_info(:run_update, _) do
new_stats = calculate_stat_data()
Process.send_after(self(), :run_update, @interval)
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 059d94e30..8e4ec8064 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -1324,14 +1324,48 @@ defmodule Pleroma.User do
|> Repo.all()
end
- @spec mute(User.t(), User.t(), boolean()) ::
+ @spec mute(User.t(), User.t(), map()) ::
{:ok, list(UserRelationship.t())} | {:error, String.t()}
- def mute(%User{} = muter, %User{} = mutee, notifications? \\ true) do
- add_to_mutes(muter, mutee, notifications?)
+ def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do
+ notifications? = Map.get(params, :notifications, true)
+ expires_in = Map.get(params, :expires_in, 0)
+
+ with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee),
+ {:ok, user_notification_mute} <-
+ (notifications? && UserRelationship.create_notification_mute(muter, mutee)) ||
+ {:ok, nil} do
+ if expires_in > 0 do
+ Pleroma.Workers.MuteExpireWorker.enqueue(
+ "unmute_user",
+ %{"muter_id" => muter.id, "mutee_id" => mutee.id},
+ schedule_in: expires_in
+ )
+ end
+
+ {:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
+ end
end
def unmute(%User{} = muter, %User{} = mutee) do
- remove_from_mutes(muter, mutee)
+ with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
+ {:ok, user_notification_mute} <-
+ UserRelationship.delete_notification_mute(muter, mutee) do
+ {:ok, [user_mute, user_notification_mute]}
+ end
+ end
+
+ def unmute(muter_id, mutee_id) do
+ with {:muter, %User{} = muter} <- {:muter, User.get_by_id(muter_id)},
+ {:mutee, %User{} = mutee} <- {:mutee, User.get_by_id(mutee_id)} do
+ unmute(muter, mutee)
+ else
+ {who, result} = error ->
+ Logger.warn(
+ "User.unmute/2 failed. #{who}: #{result}, muter_id: #{muter_id}, mutee_id: #{mutee_id}"
+ )
+
+ {:error, error}
+ end
end
def subscribe(%User{} = subscriber, %User{} = target) do
@@ -2320,23 +2354,6 @@ defmodule Pleroma.User do
UserRelationship.delete_block(user, blocked)
end
- defp add_to_mutes(%User{} = user, %User{} = muted_user, notifications?) do
- with {:ok, user_mute} <- UserRelationship.create_mute(user, muted_user),
- {:ok, user_notification_mute} <-
- (notifications? && UserRelationship.create_notification_mute(user, muted_user)) ||
- {:ok, nil} do
- {:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
- end
- end
-
- defp remove_from_mutes(user, %User{} = muted_user) do
- with {:ok, user_mute} <- UserRelationship.delete_mute(user, muted_user),
- {:ok, user_notification_mute} <-
- UserRelationship.delete_notification_mute(user, muted_user) do
- {:ok, [user_mute, user_notification_mute]}
- end
- end
-
def set_invisible(user, invisible) do
params = %{invisible: invisible}
diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex
index 4934b7788..451aa2477 100644
--- a/lib/pleroma/web/api_spec/operations/account_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/account_operation.ex
@@ -262,6 +262,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
:query,
%Schema{allOf: [BooleanLike], default: true},
"Mute notifications in addition to statuses? Defaults to `true`."
+ ),
+ Operation.parameter(
+ :expires_in,
+ :query,
+ %Schema{type: :integer, default: 0},
+ "Expire the mute in `expires_in` seconds. Default 0 for infinity"
)
],
responses: %{
@@ -723,10 +729,17 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
nullable: true,
description: "Mute notifications in addition to statuses? Defaults to true.",
default: true
+ },
+ expires_in: %Schema{
+ type: :integer,
+ nullable: true,
+ description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
+ default: 0
}
},
example: %{
- "notifications" => true
+ "notifications" => true,
+ "expires_in" => 86_400
}
}
end
diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex
index d7ebde6f6..b3b6ceb68 100644
--- a/lib/pleroma/web/api_spec/operations/status_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/status_operation.ex
@@ -223,7 +223,27 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
security: [%{"oAuth" => ["write:mutes"]}],
description: "Do not receive notifications for the thread that this status is part of.",
operationId: "StatusController.mute_conversation",
- parameters: [id_param()],
+ requestBody:
+ request_body("Parameters", %Schema{
+ type: :object,
+ properties: %{
+ expires_in: %Schema{
+ type: :integer,
+ nullable: true,
+ description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
+ default: 0
+ }
+ }
+ }),
+ parameters: [
+ id_param(),
+ Operation.parameter(
+ :expires_in,
+ :query,
+ %Schema{type: :integer, default: 0},
+ "Expire the mute in `expires_in` seconds. Default 0 for infinity"
+ )
+ ],
responses: %{
200 => status_response(),
400 => Operation.response("Error", "application/json", ApiError)
diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex
index 318ffc5d0..0ab1b115d 100644
--- a/lib/pleroma/web/common_api.ex
+++ b/lib/pleroma/web/common_api.ex
@@ -454,20 +454,46 @@ defmodule Pleroma.Web.CommonAPI do
end
end
- def add_mute(user, activity) do
+ def add_mute(user, activity, params \\ %{}) do
+ expires_in = Map.get(params, :expires_in, 0)
+
with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]),
_ <- Pleroma.Notification.mark_context_as_read(user, activity.data["context"]) do
+ if expires_in > 0 do
+ Pleroma.Workers.MuteExpireWorker.enqueue(
+ "unmute_conversation",
+ %{"user_id" => user.id, "activity_id" => activity.id},
+ schedule_in: expires_in
+ )
+ end
+
{:ok, activity}
else
{:error, _} -> {:error, dgettext("errors", "conversation is already muted")}
end
end
- def remove_mute(user, activity) do
+ def remove_mute(%User{} = user, %Activity{} = activity) do
ThreadMute.remove_mute(user.id, activity.data["context"])
{:ok, activity}
end
+ def remove_mute(user_id, activity_id) do
+ with {:user, %User{} = user} <- {:user, User.get_by_id(user_id)},
+ {:activity, %Activity{} = activity} <- {:activity, Activity.get_by_id(activity_id)} do
+ remove_mute(user, activity)
+ else
+ {what, result} = error ->
+ Logger.warn(
+ "CommonAPI.remove_mute/2 failed. #{what}: #{result}, user_id: #{user_id}, activity_id: #{
+ activity_id
+ }"
+ )
+
+ {:error, error}
+ end
+ end
+
def thread_muted?(%User{id: user_id}, %{data: %{"context" => context}})
when is_binary(context) do
ThreadMute.exists?(user_id, context)
diff --git a/lib/pleroma/web/fallback/redirect_controller.ex b/lib/pleroma/web/fallback/redirect_controller.ex
index 6f759d559..712991c18 100644
--- a/lib/pleroma/web/fallback/redirect_controller.ex
+++ b/lib/pleroma/web/fallback/redirect_controller.ex
@@ -37,9 +37,11 @@ defmodule Pleroma.Web.Fallback.RedirectController do
tags = build_tags(conn, params)
preloads = preload_data(conn, params)
+ title = "<title>#{Pleroma.Config.get([:instance, :name])}</title>"
response =
index_content
+ |> String.replace(~r/<title>.+?<\/title>/, title)
|> String.replace("<!--server-generated-meta-->", tags <> preloads)
conn
@@ -54,9 +56,11 @@ defmodule Pleroma.Web.Fallback.RedirectController do
def redirector_with_preload(conn, params) do
{:ok, index_content} = File.read(index_file_path())
preloads = preload_data(conn, params)
+ title = "<title>#{Pleroma.Config.get([:instance, :name])}</title>"
response =
index_content
+ |> String.replace(~r/<title>.+?<\/title>/, title)
|> String.replace("<!--server-generated-meta-->", preloads)
conn
diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex
index 1ae03e7e2..56c024617 100644
--- a/lib/pleroma/web/feed/feed_view.ex
+++ b/lib/pleroma/web/feed/feed_view.ex
@@ -83,7 +83,7 @@ defmodule Pleroma.Web.Feed.FeedView do
def activity_content(_), do: ""
- def activity_context(activity), do: activity.data["context"]
+ def activity_context(activity), do: escape(activity.data["context"])
def attachment_href(attachment) do
attachment["url"]
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
index a2715cf28..784fdc975 100644
--- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -394,7 +394,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
@doc "POST /api/v1/accounts/:id/mute"
def mute(%{assigns: %{user: muter, account: muted}, body_params: params} = conn, _params) do
- with {:ok, _user_relationships} <- User.mute(muter, muted, params.notifications) do
+ with {:ok, _user_relationships} <- User.mute(muter, muted, params) do
render(conn, "relationship.json", user: muter, target: muted)
else
{:error, message} -> json_response(conn, :forbidden, %{error: message})
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index 6848adace..4d9be5240 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -284,9 +284,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
end
@doc "POST /api/v1/statuses/:id/mute"
- def mute_conversation(%{assigns: %{user: user}} = conn, %{id: id}) do
+ def mute_conversation(%{assigns: %{user: user}, body_params: params} = conn, %{id: id}) do
with %Activity{} = activity <- Activity.get_by_id(id),
- {:ok, activity} <- CommonAPI.add_mute(user, activity) do
+ {:ok, activity} <- CommonAPI.add_mute(user, activity, params) do
try_render(conn, "show.json", activity: activity, for: user, as: :activity)
end
end
diff --git a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex
index 78350f2aa..3fd150c4e 100644
--- a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex
+++ b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex
@@ -12,7 +12,7 @@
<link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/>
<%= if @data["summary"] do %>
- <summary><%= @data["summary"] %></summary>
+ <summary><%= escape(@data["summary"]) %></summary>
<% end %>
<%= if @activity.local do %>
diff --git a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex
index a304a16af..42960de7d 100644
--- a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex
+++ b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex
@@ -12,7 +12,7 @@
<link rel="ostatus:conversation"><%= activity_context(@activity) %></link>
<%= if @data["summary"] do %>
- <description><%= @data["summary"] %></description>
+ <description><%= escape(@data["summary"]) %></description>
<% end %>
<%= if @activity.local do %>
diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex
new file mode 100644
index 000000000..32a12ba85
--- /dev/null
+++ b/lib/pleroma/workers/mute_expire_worker.ex
@@ -0,0 +1,20 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.MuteExpireWorker do
+ use Pleroma.Workers.WorkerHelper, queue: "mute_expire"
+
+ @impl Oban.Worker
+ def perform(%Job{args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id}}) do
+ Pleroma.User.unmute(muter_id, mutee_id)
+ :ok
+ end
+
+ def perform(%Job{
+ args: %{"op" => "unmute_conversation", "user_id" => user_id, "activity_id" => activity_id}
+ }) do
+ Pleroma.Web.CommonAPI.remove_mute(user_id, activity_id)
+ :ok
+ end
+end
diff --git a/test/mix/tasks/pleroma/instance_test.exs b/test/mix/tasks/pleroma/instance_test.exs
index fe69a2def..8a02710ee 100644
--- a/test/mix/tasks/pleroma/instance_test.exs
+++ b/test/mix/tasks/pleroma/instance_test.exs
@@ -5,8 +5,6 @@
defmodule Mix.Tasks.Pleroma.InstanceTest do
use ExUnit.Case
- @release_env_file "./test/pleroma.test.env"
-
setup do
File.mkdir_p!(tmp_path())
@@ -18,8 +16,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
File.rm_rf(Path.join(static_dir, "robots.txt"))
end
- if File.exists?(@release_env_file), do: File.rm_rf(@release_env_file)
-
Pleroma.Config.put([:instance, :static_dir], static_dir)
end)
@@ -73,9 +69,7 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
"--dedupe-uploads",
"n",
"--anonymize-uploads",
- "n",
- "--release-env-file",
- @release_env_file
+ "n"
])
end
@@ -97,9 +91,6 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
assert generated_config =~ "filters: [Pleroma.Upload.Filter.ExifTool]"
assert File.read!(tmp_path() <> "setup.psql") == generated_setup_psql()
assert File.exists?(Path.expand("./test/instance/static/robots.txt"))
- assert File.exists?(@release_env_file)
-
- assert File.read!(@release_env_file) =~ ~r/^RELEASE_COOKIE=.*/
end
defp generated_setup_psql do
diff --git a/test/mix/tasks/pleroma/release_env_test.exs b/test/mix/tasks/pleroma/release_env_test.exs
deleted file mode 100644
index 519f1eba9..000000000
--- a/test/mix/tasks/pleroma/release_env_test.exs
+++ /dev/null
@@ -1,30 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Mix.Tasks.Pleroma.ReleaseEnvTest do
- use ExUnit.Case
- import ExUnit.CaptureIO, only: [capture_io: 1]
-
- @path "config/pleroma.test.env"
-
- def do_clean do
- if File.exists?(@path) do
- File.rm_rf(@path)
- end
- end
-
- setup do
- do_clean()
- on_exit(fn -> do_clean() end)
- :ok
- end
-
- test "generate pleroma.env" do
- assert capture_io(fn ->
- Mix.Tasks.Pleroma.ReleaseEnv.run(["gen", "--path", @path, "--force"])
- end) =~ "The file generated"
-
- assert File.read!(@path) =~ "RELEASE_COOKIE="
- end
-end
diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs
index a74fb7bc2..92c0bc8b6 100644
--- a/test/pleroma/notification_test.exs
+++ b/test/pleroma/notification_test.exs
@@ -229,7 +229,7 @@ defmodule Pleroma.NotificationTest do
muter = insert(:user)
muted = insert(:user)
- {:ok, _user_relationships} = User.mute(muter, muted, false)
+ {:ok, _user_relationships} = User.mute(muter, muted, %{notifications: false})
{:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
@@ -1015,7 +1015,7 @@ defmodule Pleroma.NotificationTest do
test "it returns notifications for muted user without notifications", %{user: user} do
muted = insert(:user)
- {:ok, _user_relationships} = User.mute(user, muted, false)
+ {:ok, _user_relationships} = User.mute(user, muted, %{notifications: false})
{:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index 9ae52d594..c678dadb3 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -1008,6 +1008,27 @@ defmodule Pleroma.UserTest do
assert User.muted_notifications?(user, muted_user)
end
+ test "expiring" do
+ user = insert(:user)
+ muted_user = insert(:user)
+
+ {:ok, _user_relationships} = User.mute(user, muted_user, %{expires_in: 60})
+ assert User.mutes?(user, muted_user)
+
+ worker = Pleroma.Workers.MuteExpireWorker
+ args = %{"op" => "unmute_user", "muter_id" => user.id, "mutee_id" => muted_user.id}
+
+ assert_enqueued(
+ worker: worker,
+ args: args
+ )
+
+ assert :ok = perform_job(worker, args)
+
+ refute User.mutes?(user, muted_user)
+ refute User.muted_notifications?(user, muted_user)
+ end
+
test "it unmutes users" do
user = insert(:user)
muted_user = insert(:user)
@@ -1019,6 +1040,17 @@ defmodule Pleroma.UserTest do
refute User.muted_notifications?(user, muted_user)
end
+ test "it unmutes users by id" do
+ user = insert(:user)
+ muted_user = insert(:user)
+
+ {:ok, _user_relationships} = User.mute(user, muted_user)
+ {:ok, _user_mute} = User.unmute(user.id, muted_user.id)
+
+ refute User.mutes?(user, muted_user)
+ refute User.muted_notifications?(user, muted_user)
+ end
+
test "it mutes user without notifications" do
user = insert(:user)
muted_user = insert(:user)
@@ -1026,7 +1058,7 @@ defmodule Pleroma.UserTest do
refute User.mutes?(user, muted_user)
refute User.muted_notifications?(user, muted_user)
- {:ok, _user_relationships} = User.mute(user, muted_user, false)
+ {:ok, _user_relationships} = User.mute(user, muted_user, %{notifications: false})
assert User.mutes?(user, muted_user)
refute User.muted_notifications?(user, muted_user)
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index c5b90ad84..8e87e69fe 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -3,8 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.CommonAPITest do
- use Pleroma.DataCase
use Oban.Testing, repo: Pleroma.Repo
+ use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Chat
@@ -922,12 +922,34 @@ defmodule Pleroma.Web.CommonAPITest do
assert CommonAPI.thread_muted?(user, activity)
end
+ test "add expiring mute", %{user: user, activity: activity} do
+ {:ok, _} = CommonAPI.add_mute(user, activity, %{expires_in: 60})
+ assert CommonAPI.thread_muted?(user, activity)
+
+ worker = Pleroma.Workers.MuteExpireWorker
+ args = %{"op" => "unmute_conversation", "user_id" => user.id, "activity_id" => activity.id}
+
+ assert_enqueued(
+ worker: worker,
+ args: args
+ )
+
+ assert :ok = perform_job(worker, args)
+ refute CommonAPI.thread_muted?(user, activity)
+ end
+
test "remove mute", %{user: user, activity: activity} do
CommonAPI.add_mute(user, activity)
{:ok, _} = CommonAPI.remove_mute(user, activity)
refute CommonAPI.thread_muted?(user, activity)
end
+ test "remove mute by ids", %{user: user, activity: activity} do
+ CommonAPI.add_mute(user, activity)
+ {:ok, _} = CommonAPI.remove_mute(user.id, activity.id)
+ refute CommonAPI.thread_muted?(user, activity)
+ end
+
test "check that mutes can't be duplicate", %{user: user, activity: activity} do
CommonAPI.add_mute(user, activity)
{:error, _} = CommonAPI.add_mute(user, activity)
diff --git a/test/pleroma/web/feed/user_controller_test.exs b/test/pleroma/web/feed/user_controller_test.exs
index eabfe3a63..16f002717 100644
--- a/test/pleroma/web/feed/user_controller_test.exs
+++ b/test/pleroma/web/feed/user_controller_test.exs
@@ -12,16 +12,17 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.Feed.FeedView
setup do: clear_config([:static_fe, :enabled], false)
describe "feed" do
setup do: clear_config([:feed])
- test "gets an atom feed", %{conn: conn} do
+ setup do
Config.put(
[:feed, :post_title],
- %{max_length: 10, omission: "..."}
+ %{max_length: 15, omission: "..."}
)
activity = insert(:note_activity)
@@ -29,7 +30,8 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
note =
insert(:note,
data: %{
- "content" => "This is :moominmamma: note ",
+ "content" => "This & this is :moominmamma: note ",
+ "source" => "This & this is :moominmamma: note ",
"attachment" => [
%{
"url" => [
@@ -37,7 +39,9 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
]
}
],
- "inReplyTo" => activity.data["id"]
+ "inReplyTo" => activity.data["id"],
+ "context" => "2hu & as",
+ "summary" => "2hu & as"
}
)
@@ -48,7 +52,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
insert(:note,
user: user,
data: %{
- "content" => "42 This is :moominmamma: note ",
+ "content" => "42 & This is :moominmamma: note ",
"inReplyTo" => activity.data["id"]
}
)
@@ -56,6 +60,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
note_activity2 = insert(:note_activity, note: note2)
object = Object.normalize(note_activity)
+ [user: user, object: object, max_id: note_activity2.id]
+ end
+
+ test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do
resp =
conn
|> put_req_header("accept", "application/atom+xml")
@@ -67,13 +75,15 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
- assert activity_titles == ['42 This...', 'This is...']
- assert resp =~ object.data["content"]
+ assert activity_titles == ['42 &amp; Thi...', 'This &amp; t...']
+ assert resp =~ FeedView.escape(object.data["content"])
+ assert resp =~ FeedView.escape(object.data["summary"])
+ assert resp =~ FeedView.escape(object.data["context"])
resp =
conn
|> put_req_header("accept", "application/atom+xml")
- |> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id})
+ |> get("/users/#{user.nickname}/feed", %{"max_id" => max_id})
|> response(200)
activity_titles =
@@ -81,47 +91,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
- assert activity_titles == ['This is...']
+ assert activity_titles == ['This &amp; t...']
end
- test "gets a rss feed", %{conn: conn} do
- Pleroma.Config.put(
- [:feed, :post_title],
- %{max_length: 10, omission: "..."}
- )
-
- activity = insert(:note_activity)
-
- note =
- insert(:note,
- data: %{
- "content" => "This is :moominmamma: note ",
- "attachment" => [
- %{
- "url" => [
- %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}
- ]
- }
- ],
- "inReplyTo" => activity.data["id"]
- }
- )
-
- note_activity = insert(:note_activity, note: note)
- user = User.get_cached_by_ap_id(note_activity.data["actor"])
-
- note2 =
- insert(:note,
- user: user,
- data: %{
- "content" => "42 This is :moominmamma: note ",
- "inReplyTo" => activity.data["id"]
- }
- )
-
- note_activity2 = insert(:note_activity, note: note2)
- object = Object.normalize(note_activity)
-
+ test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do
resp =
conn
|> put_req_header("accept", "application/rss+xml")
@@ -133,13 +106,15 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//item/title/text()"l)
- assert activity_titles == ['42 This...', 'This is...']
- assert resp =~ object.data["content"]
+ assert activity_titles == ['42 &amp; Thi...', 'This &amp; t...']
+ assert resp =~ FeedView.escape(object.data["content"])
+ assert resp =~ FeedView.escape(object.data["summary"])
+ assert resp =~ FeedView.escape(object.data["context"])
resp =
conn
|> put_req_header("accept", "application/rss+xml")
- |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id})
+ |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => max_id})
|> response(200)
activity_titles =
@@ -147,7 +122,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|> SweetXml.parse()
|> SweetXml.xpath(~x"//item/title/text()"l)
- assert activity_titles == ['This is...']
+ assert activity_titles == ['This &amp; t...']
end
test "returns 404 for a missing feed", %{conn: conn} do
diff --git a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
index 70ef0e8b5..5fd518c60 100644
--- a/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/notification_controller_test.exs
@@ -502,7 +502,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
- {:ok, _user_relationships} = User.mute(user, user2, false)
+ {:ok, _user_relationships} = User.mute(user, user2, %{notifications: false})
conn = get(conn, "/api/v1/notifications")
diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs
index 203e61c71..139e32362 100644
--- a/test/pleroma/web/mastodon_api/views/account_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs
@@ -277,7 +277,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
{:ok, user} = User.follow(user, other_user)
{:ok, other_user} = User.follow(other_user, user)
{:ok, _subscription} = User.subscribe(user, other_user)
- {:ok, _user_relationships} = User.mute(user, other_user, true)
+ {:ok, _user_relationships} = User.mute(user, other_user, %{notifications: true})
{:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
expected =