From: lain Date: Sat, 24 Aug 2019 13:48:33 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/develop' into sixohsix/pleroma-post_expiration X-Git-Url: https://git.squeep.com/?a=commitdiff_plain;h=cc6c0b4ba6762e6a9b0a90c3dcda3f95283eb22a;p=akkoma Merge remote-tracking branch 'origin/develop' into sixohsix/pleroma-post_expiration --- cc6c0b4ba6762e6a9b0a90c3dcda3f95283eb22a diff --cc CHANGELOG.md index f64506637,880fba58a..949577842 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@@ -32,8 -38,21 +38,25 @@@ The format is based on [Keep a Changelo - Rich Media: Parser failing when no TTL can be found by image TTL setters - Rich Media: The crawled URL is now spliced into the rich media data. - ActivityPub S2S: sharedInbox usage has been mostly aligned with the rules in the AP specification. + - ActivityPub S2S: remote user deletions now work the same as local user deletions. + - ActivityPub S2S: POST requests are now signed with `(request-target)` pseudo-header. + - Not being able to access the Mastodon FE login page on private instances + - Invalid SemVer version generation, when the current branch does not have commits ahead of tag/checked out on a tag + - Pleroma.Upload base_url was not automatically whitelisted by MediaProxy. Now your custom CDN or file hosting will be accessed directly as expected. + - Report email not being sent to admins when the reporter is a remote user + - MRF: ensure that subdomain_match calls are case-insensitive + - Reverse Proxy limiting `max_body_length` was incorrectly defined and only checked `Content-Length` headers which may not be sufficient in some circumstances + - MRF: fix use of unserializable keyword lists in describe() implementations + - ActivityPub: Deactivated user deletion ### Added ++- Expiring/ephemeral activites. All activities can have expires_on value set, which controls when they should be deleted automatically. ++- Mastodon API: in post_status, the expires_in parameter lets you set the number of minutes until an activity expires. It must be at least one hour. ++- Mastodon API: all status JSON responses contain a `pleroma.expires_on` item which states when an activity will expire. The value is only shown to the user who created the activity. To everyone else it's empty. ++- Configuration: `ActivityExpiration.enabled` controls whether expired activites will get deleted at the appropriate time. Enabled by default. + - Conversations: Add Pleroma-specific conversation endpoints and status posting extensions. Run the `bump_all_conversations` task again to create the necessary data. + - **Breaking:** MRF describe API, which adds support for exposing configuration information about MRF policies to NodeInfo. + Custom modules will need to be updated by adding, at the very least, `def describe, do: {:ok, %{}}` to the MRF policy modules. - MRF: Support for priming the mediaproxy cache (`Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`) - MRF: Support for excluding specific domains from Transparency. - MRF: Support for filtering posts based on who they mention (`Pleroma.Web.ActivityPub.MRF.MentionPolicy`) diff --cc config/config.exs index 2887353fb,118f697b3..e58454d68 --- a/config/config.exs +++ b/config/config.exs @@@ -535,10 -562,10 +563,12 @@@ config :pleroma, :rate_limit relation_id_action: {60_000, 2}, statuses_actions: {10_000, 15}, status_id_action: {60_000, 3}, - password_reset: {1_800_000, 5} + password_reset: {1_800_000, 5}, + account_confirmation_resend: {8_640_000, 5}, + ap_routes: {60_000, 15} +config :pleroma, Pleroma.ActivityExpiration, enabled: true + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --cc config/test.exs index 3f606aa81,30a51f734..567780987 --- a/config/test.exs +++ b/config/test.exs @@@ -80,12 -82,15 +82,14 @@@ rum_enabled = System.get_env("RUM_ENABL config :pleroma, :database, rum_enabled: rum_enabled IO.puts("RUM enabled: #{rum_enabled}") + config :joken, default_signer: "yU8uHKq+yyAkZ11Hx//jcdacWc8yQ1bxAAGrplzB0Zwwjkp35v0RK9SO8WTPr6QZ" + config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock -try do +if File.exists?("./config/test.secret.exs") do import_config "test.secret.exs" -rescue - _ -> - IO.puts( - "You may want to create test.secret.exs to declare custom database connection parameters." - ) +else + IO.puts( + "You may want to create test.secret.exs to declare custom database connection parameters." + ) end diff --cc docs/api/differences_in_mastoapi_responses.md index 168a13f4e,79ca531b8..197c465d8 --- a/docs/api/differences_in_mastoapi_responses.md +++ b/docs/api/differences_in_mastoapi_responses.md @@@ -80,7 -86,7 +87,8 @@@ Additional parameters can be added to t - `content_type`: string, contain the MIME type of the status, it is transformed into HTML by the backend. You can get the list of the supported MIME types with the nodeinfo endpoint. - `to`: A list of nicknames (like `lain@soykaf.club` or `lain` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for for post visibility are not affected by this and will still apply. - `visibility`: string, besides standard MastoAPI values (`direct`, `private`, `unlisted` or `public`) it can be used to address a List by setting it to `list:LIST_ID`. +- `expires_on`: datetime (iso8601), sets when the posted activity should expire. When a posted activity expires it will be deleted from the server, and a delete request for it will be federated. + - `in_reply_to_conversation_id`: Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`. ## PATCH `/api/v1/update_credentials` diff --cc lib/pleroma/application.ex index 42e4a1dfa,25e56b9e2..1e4de272c --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@@ -29,112 -30,18 +30,19 @@@ defmodule Pleroma.Application d # Define workers and child supervisors to be supervised children = [ - # Start the Ecto repository - %{id: Pleroma.Repo, start: {Pleroma.Repo, :start_link, []}, type: :supervisor}, - %{id: Pleroma.Config.TransferTask, start: {Pleroma.Config.TransferTask, :start_link, []}}, - %{id: Pleroma.Emoji, start: {Pleroma.Emoji, :start_link, []}}, - %{id: Pleroma.Captcha, start: {Pleroma.Captcha, :start_link, []}}, - %{ - id: :cachex_used_captcha_cache, - start: - {Cachex, :start_link, - [ - :used_captcha_cache, - [ - ttl_interval: - :timer.seconds(Pleroma.Config.get!([Pleroma.Captcha, :seconds_valid])) - ] - ]} - }, - %{ - id: :cachex_user, - start: - {Cachex, :start_link, - [ - :user_cache, - [ - default_ttl: 25_000, - ttl_interval: 1000, - limit: 2500 - ] - ]} - }, - %{ - id: :cachex_object, - start: - {Cachex, :start_link, - [ - :object_cache, - [ - default_ttl: 25_000, - ttl_interval: 1000, - limit: 2500 - ] - ]} - }, - %{ - id: :cachex_rich_media, - start: - {Cachex, :start_link, - [ - :rich_media_cache, - [ - default_ttl: :timer.minutes(120), - limit: 5000 - ] - ]} - }, - %{ - id: :cachex_scrubber, - start: - {Cachex, :start_link, - [ - :scrubber_cache, - [ - limit: 2500 - ] - ]} - }, - %{ - id: :cachex_idem, - start: - {Cachex, :start_link, - [ - :idempotency_cache, - [ - expiration: - expiration( - default: :timer.seconds(6 * 60 * 60), - interval: :timer.seconds(60) - ), - limit: 2500 - ] - ]} - }, - %{id: Pleroma.FlakeId, start: {Pleroma.FlakeId, :start_link, []}}, - %{ - id: Pleroma.ScheduledActivityWorker, - start: {Pleroma.ScheduledActivityWorker, :start_link, []} - }, - %{ - id: Pleroma.ActivityExpirationWorker, - start: {Pleroma.ActivityExpirationWorker, :start_link, []} - } + Pleroma.Repo, + Pleroma.Config.TransferTask, + Pleroma.Emoji, + Pleroma.Captcha, + Pleroma.FlakeId, - Pleroma.ScheduledActivityWorker ++ Pleroma.ScheduledActivityWorker, ++ Pleroma.ActiviyExpirationWorker ] ++ + cachex_children() ++ hackney_pool_children() ++ [ - %{ - id: Pleroma.Web.Federator.RetryQueue, - start: {Pleroma.Web.Federator.RetryQueue, :start_link, []} - }, - %{ - id: Pleroma.Web.OAuth.Token.CleanWorker, - start: {Pleroma.Web.OAuth.Token.CleanWorker, :start_link, []} - }, - %{ - id: Pleroma.Stats, - start: {Pleroma.Stats, :start_link, []} - }, + Pleroma.Web.Federator.RetryQueue, + Pleroma.Stats, %{ id: :web_push_init, start: {Task, :start_link, [&Pleroma.Web.Push.init/0]}, diff --cc lib/pleroma/web/common_api/common_api.ex index 261d60392,72da46263..69120cc19 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@@ -4,7 -4,7 +4,8 @@@ defmodule Pleroma.Web.CommonAPI do alias Pleroma.Activity + alias Pleroma.ActivityExpiration + alias Pleroma.Conversation.Participation alias Pleroma.Formatter alias Pleroma.Object alias Pleroma.ThreadMute @@@ -225,11 -221,11 +232,12 @@@ mentioned_users <- for({_, mentioned_user} <- mentions, do: mentioned_user.ap_id), addressed_users <- get_addressed_users(mentioned_users, data["to"]), {poll, poll_emoji} <- make_poll_data(data), - {to, cc} <- get_to_and_cc(user, addressed_users, in_reply_to, visibility), - context <- make_context(in_reply_to), + {to, cc} <- + get_to_and_cc(user, addressed_users, in_reply_to, visibility, in_reply_to_conversation), + context <- make_context(in_reply_to, in_reply_to_conversation), cw <- data["spoiler_text"] || "", sensitive <- data["sensitive"] || Enum.member?(tags, {"#nsfw", "nsfw"}), + {:ok, expires_at} <- check_expiry_date(data["expires_at"]), full_payload <- String.trim(status <> cw), :ok <- validate_character_limit(full_payload, attachments, limit), object <- diff --cc lib/pleroma/web/mastodon_api/views/status_view.ex index 7264dcafb,42fbdf51b..a4ee0b5dd --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@@ -5,8 -5,11 +5,12 @@@ defmodule Pleroma.Web.MastodonAPI.StatusView do use Pleroma.Web, :view + require Pleroma.Constants + alias Pleroma.Activity + alias Pleroma.ActivityExpiration + alias Pleroma.Conversation + alias Pleroma.Conversation.Participation alias Pleroma.HTML alias Pleroma.Object alias Pleroma.Repo @@@ -273,7 -288,7 +298,8 @@@ in_reply_to_account_acct: reply_to_user && reply_to_user.nickname, content: %{"text/plain" => content_plaintext}, spoiler_text: %{"text/plain" => summary_plaintext}, - expires_at: expires_at ++ expires_at: expires_at, + direct_conversation_id: direct_conversation_id } } end diff --cc test/web/common_api/common_api_test.exs index 210314a4a,bcbaad665..5fda91438 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@@ -157,26 -203,7 +203,24 @@@ defmodule Pleroma.Web.CommonAPITest d assert {:error, "The status is over the character limit"} = CommonAPI.post(user, %{"status" => "foobar"}) - - Pleroma.Config.put([:instance, :limit], limit) end + + test "it can handle activities that expire" do + user = insert(:user) + + expires_at = + NaiveDateTime.utc_now() + |> NaiveDateTime.truncate(:second) + |> NaiveDateTime.add(1_000_000, :second) + + expires_at_iso8601 = expires_at |> NaiveDateTime.to_iso8601() + + assert {:ok, activity} = + CommonAPI.post(user, %{"status" => "chai", "expires_at" => expires_at_iso8601}) + + assert expiration = Pleroma.ActivityExpiration.get_by_activity_id(activity.id) + assert expiration.scheduled_at == expires_at + end end describe "reactions" do diff --cc test/web/mastodon_api/mastodon_api_controller_test.exs index fbe0ab375,77430e9c9..c05c39db6 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@@ -7,7 -7,7 +7,8 @@@ defmodule Pleroma.Web.MastodonAPI.Masto alias Ecto.Changeset alias Pleroma.Activity + alias Pleroma.ActivityExpiration + alias Pleroma.Config alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo diff --cc test/web/mastodon_api/status_view_test.exs index 073c69659,c983b494f..1b6beb6d2 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@@ -134,7 -149,7 +149,8 @@@ defmodule Pleroma.Web.MastodonAPI.Statu in_reply_to_account_acct: nil, content: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["content"])}, spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])}, - expires_at: nil ++ expires_at: nil, + direct_conversation_id: nil } }