Merge branch 'develop' into global-status-expiration
authorEgor Kislitsyn <egor@kislitsyn.com>
Fri, 20 Mar 2020 18:08:34 +0000 (22:08 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Fri, 20 Mar 2020 18:08:34 +0000 (22:08 +0400)
1  2 
CHANGELOG.md
config/config.exs
config/description.exs
docs/configuration/cheatsheet.md
test/web/activity_pub/activity_pub_test.exs
test/workers/cron/purge_expired_activities_worker_test.exs

diff --combined CHANGELOG.md
index 77cd35990b5bbd4cb6fc3a4fc139e4323ee682b0,15a073c6488eb714d26ef4f6c25b706e7f7344e8..79b4bbb5318c5b3ce1fa78fd1bbeb114f7252d0f
@@@ -6,8 -6,18 +6,19 @@@ The format is based on [Keep a Changelo
  ## [unreleased]
  ### Changed
  - **Breaking:** BBCode and Markdown formatters will no longer return any `\n` and only use `<br/>` for newlines
 +- MFR policy to set global expiration for all local Create activities
  
+ ### Removed
+ - **Breaking:** removed `with_move` parameter from notifications timeline.
+ ### Added
+ - NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
+ - Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
+ <details>
+   <summary>API Changes</summary>
+ - Mastodon API: Support for `include_types` in `/api/v1/notifications`.
+ </details>
  ## [2.0.0] - 2019-03-08
  ### Security
  - Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request.
diff --combined config/config.exs
index c976691fbfb7a5d5f849565fe03e0eb033e6035b,2ab9391074f9851c0ff85b29884a63b26da7f174..05c55074afd682bc6ae97e6e6076eaad11546385
@@@ -365,8 -365,6 +365,8 @@@ config :pleroma, :mrf_keyword
  
  config :pleroma, :mrf_subchain, match_actor: %{}
  
 +config :pleroma, :mrf_activity_expiration, days: 365
 +
  config :pleroma, :mrf_vocabulary,
    accept: [],
    reject: []
@@@ -626,6 -624,11 +626,11 @@@ config :pleroma, Pleroma.Repo
    parameters: [gin_fuzzy_search_limit: "500"],
    prepare: :unnamed
  
+ config :pleroma, :restrict_unauthenticated,
+   timelines: %{local: false, federated: false},
+   profiles: %{local: false, remote: false},
+   activities: %{local: false, remote: false}
  # 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 --combined config/description.exs
index 373995ed65cec1c8d27da5e248f85c8fa4aedbd7,3781fb9cb7dcf27a1a5cce96456f879a6c8b0eb8..9b2acea7eb8c939ce3f3277850bb3d7eb7f53f3d
@@@ -1346,21 -1346,6 +1346,21 @@@ config :pleroma, :config_description, 
        }
      ]
    },
 +  %{
 +    group: :pleroma,
 +    key: :mrf_activity_expiration,
 +    label: "MRF Activity Expiration Policy",
 +    type: :group,
 +    description: "Adds expiration to all local Create activities",
 +    children: [
 +      %{
 +        key: :days,
 +        type: :integer,
 +        description: "Default global expiration time for all local Create activities (in days)",
 +        suggestions: [90, 365]
 +      }
 +    ]
 +  },
    %{
      group: :pleroma,
      key: :mrf_subchain,
          suggestions: [2]
        }
      ]
+   },
+   %{
+     group: :pleroma,
+     key: :restrict_unauthenticated,
+     type: :group,
+     description:
+       "Disallow viewing timelines, user profiles and statuses for unauthenticated users.",
+     children: [
+       %{
+         key: :timelines,
+         type: :map,
+         description: "Settings for public and federated timelines.",
+         children: [
+           %{
+             key: :local,
+             type: :boolean,
+             description: "Disallow view public timeline."
+           },
+           %{
+             key: :federated,
+             type: :boolean,
+             description: "Disallow view federated timeline."
+           }
+         ]
+       },
+       %{
+         key: :profiles,
+         type: :map,
+         description: "Settings for user profiles.",
+         children: [
+           %{
+             key: :local,
+             type: :boolean,
+             description: "Disallow view local user profiles."
+           },
+           %{
+             key: :remote,
+             type: :boolean,
+             description: "Disallow view remote user profiles."
+           }
+         ]
+       },
+       %{
+         key: :activities,
+         type: :map,
+         description: "Settings for statuses.",
+         children: [
+           %{
+             key: :local,
+             type: :boolean,
+             description: "Disallow view local statuses."
+           },
+           %{
+             key: :remote,
+             type: :boolean,
+             description: "Disallow view remote statuses."
+           }
+         ]
+       }
+     ]
    }
  ]
index 2974312c45de68c68265595d162f776a422ca4f9,d16435e11bc5c9961dedea363b0a7e213bf94f6d..ee1909d6602aef318b084c9da7d358014fb941f9
@@@ -35,7 -35,7 +35,7 @@@ To add configuration to your config fil
  * `rewrite_policy`: Message Rewrite Policy, either one or a list. Here are the ones available by default:
      * `Pleroma.Web.ActivityPub.MRF.NoOpPolicy`: Doesn’t modify activities (default).
      * `Pleroma.Web.ActivityPub.MRF.DropPolicy`: Drops all activities. It generally doesn’t makes sense to use in production.
 -    * `Pleroma.Web.ActivityPub.MRF.SimplePolicy`: Restrict the visibility of activities from certains instances (See [`:mrf_simple`](#mrf_simple)).
 +    * `Pleroma.Web.ActivityPub.MRF.SimplePolicy`: Restrict the visibility of activities from certain instances (See [`:mrf_simple`](#mrf_simple)).
      * `Pleroma.Web.ActivityPub.MRF.TagPolicy`: Applies policies to individual users based on tags, which can be set using pleroma-fe/admin-fe/any other app that supports Pleroma Admin API. For example it allows marking posts from individual users nsfw (sensitive).
      * `Pleroma.Web.ActivityPub.MRF.SubchainPolicy`: Selectively runs other MRF policies when messages match (See [`:mrf_subchain`](#mrf_subchain)).
      * `Pleroma.Web.ActivityPub.MRF.RejectNonPublic`: Drops posts with non-public visibility settings (See [`:mrf_rejectnonpublic`](#mrf_rejectnonpublic)).
@@@ -45,8 -45,7 +45,8 @@@
      * `Pleroma.Web.ActivityPub.MRF.MentionPolicy`: Drops posts mentioning configurable users. (See [`:mrf_mention`](#mrf_mention)).
      * `Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`: Restricts activities to a configured set of vocabulary. (See [`:mrf_vocabulary`](#mrf_vocabulary)).
      * `Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy`: Rejects or delists posts based on their age when received. (See [`:mrf_object_age`](#mrf_object_age)).
 -* `public`: Makes the client API in authentificated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network.
 +    * `Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy`: Adds expiration to all local Create activities (see [`:mrf_activity_expiration`](#mrf_activity_expiration)).
 +* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network.
  * `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send.
  * `managed_config`: Whenether the config for pleroma-fe is configured in [:frontend_configurations](#frontend_configurations) or in ``static/config.json``.
  * `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML).
@@@ -139,16 -138,13 +139,17 @@@ config :pleroma, :mrf_user_allowlist
  ```
  
  #### :mrf_object_age
- * `threshold`: Required age (in seconds) of a post before actions are taken.
+ * `threshold`: Required time offset (in seconds) compared to your server clock of an incoming post before actions are taken.
+   e.g., A value of 900 results in any post with a timestamp older than 15 minutes will be acted upon.
  * `actions`: A list of actions to apply to the post:
    * `:delist` removes the post from public timelines
    * `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines
    * `:reject` rejects the message entirely
  
 +#### :mrf_activity_expiration
 +
 +* `days`: Default global expiration time for all local Create activities (in days)
 +
  ### :activitypub
  * `unfollow_blocked`: Whether blocks result in people getting unfollowed
  * `outgoing_blocks`: Whether to federate blocks to other instances
@@@ -876,3 -872,21 +877,21 @@@ config :auto_linker
  ## :configurable_from_database
  
  Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information.
+ ## Restrict entities access for unauthenticated users
+ ### :restrict_unauthenticated
+ Restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
+ * `timelines` - public and federated timelines
+   * `local` - public timeline
+   * `federated`
+ * `profiles` - user profiles
+   * `local`
+   * `remote`
+ * `activities` - statuses
+   * `local`
+   * `remote`
index 8c599faf3a5d3075d08eb9f2a4514e696b7b35aa,a43dd34f01fa79ddb0889f05eb8d40243e9cfe58..31d441d38c20482d33eda4950f23fc51728da8e1
@@@ -27,7 -27,7 +27,7 @@@ defmodule Pleroma.Web.ActivityPub.Activ
      :ok
    end
  
-   clear_config([:instance, :federating])
+   setup do: clear_config([:instance, :federating])
  
    describe "streaming out participations" do
      test "it streams them out" do
    end
  
    describe "deletion" do
-     clear_config([:instance, :rewrite_policy])
+     setup do: clear_config([:instance, :rewrite_policy])
  
      test "it reverts deletion on error" do
        note = insert(:note_activity)
    end
  
    describe "update" do
-     clear_config([:instance, :max_pinned_statuses])
+     setup do: clear_config([:instance, :max_pinned_statuses])
  
      test "it creates an update activity with the new user data" do
        user = insert(:user)
  
        activity = %Activity{activity | object: nil}
  
-       assert [%Notification{activity: ^activity}] =
-                Notification.for_user(follower, %{with_move: true})
+       assert [%Notification{activity: ^activity}] = Notification.for_user(follower)
  
-       assert [%Notification{activity: ^activity}] =
-                Notification.for_user(follower_move_opted_out, %{with_move: true})
+       assert [%Notification{activity: ^activity}] = Notification.for_user(follower_move_opted_out)
      end
  
      test "old user must be in the new user's `also_known_as` list" do
                 ActivityPub.move(old_user, new_user)
      end
    end
-     clear_config([:instance, :rewrite_policy])
 +
 +  describe "global activity expiration" do
++    setup do: clear_config([:instance, :rewrite_policy])
 +
 +    test "creates an activity expiration for local Create activities" do
 +      Pleroma.Config.put(
 +        [:instance, :rewrite_policy],
 +        Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
 +      )
 +
 +      {:ok, %{id: id_create}} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
 +      {:ok, _follow} = ActivityBuilder.insert(%{"type" => "Follow", "context" => "3hu"})
 +
 +      assert [%{activity_id: ^id_create}] = Pleroma.ActivityExpiration |> Repo.all()
 +    end
 +  end
  end
index 11b696bd80b1f3cdf10969e691060bc7b95e6f49,5864f9e5f675f2d420cad8ac39de3b1b3ec8b94e..85ae1e5ef4e9972f6323d22424fc1bdf5ef127f1
@@@ -11,8 -11,7 +11,10 @@@ defmodule Pleroma.Workers.Cron.PurgeExp
    import Pleroma.Factory
    import ExUnit.CaptureLog
  
-   clear_config([ActivityExpiration, :enabled])
-   clear_config([:instance, :rewrite_policy])
 -  setup do: clear_config([ActivityExpiration, :enabled])
++  setup do 
++      clear_config([ActivityExpiration, :enabled])
++    clear_config([:instance, :rewrite_policy])
++  end
  
    test "deletes an expiration activity" do
      Pleroma.Config.put([ActivityExpiration, :enabled], true)
      refute Pleroma.Repo.get(Pleroma.ActivityExpiration, expiration.id)
    end
  
 +  test "works with ActivityExpirationPolicy" do
 +    Pleroma.Config.put([ActivityExpiration, :enabled], true)
 +
 +    Pleroma.Config.put(
 +      [:instance, :rewrite_policy],
 +      Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
 +    )
 +
 +    user = insert(:user)
 +
 +    days = Pleroma.Config.get([:mrf_activity_expiration, :days], 365)
 +
 +    {:ok, %{id: id} = activity} = Pleroma.Web.CommonAPI.post(user, %{"status" => "cofe"})
 +
 +    past_date =
 +      NaiveDateTime.utc_now() |> Timex.shift(days: -days) |> NaiveDateTime.truncate(:second)
 +
 +    activity
 +    |> Repo.preload(:expiration)
 +    |> Map.get(:expiration)
 +    |> Ecto.Changeset.change(%{scheduled_at: past_date})
 +    |> Repo.update!()
 +
 +    Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(:ops, :pid)
 +
 +    assert [%{data: %{"type" => "Delete", "deleted_activity_id" => ^id}}] =
 +             Pleroma.Repo.all(Pleroma.Activity)
 +  end
 +
    describe "delete_activity/1" do
      test "adds log message if activity isn't find" do
        assert capture_log([level: :error], fn ->