Merge branch '2064-image-blanking' into 'develop'
authorHaelwenn <contact+git.pleroma.social@hacktivis.me>
Tue, 18 Aug 2020 19:02:33 +0000 (19:02 +0000)
committerHaelwenn <contact+git.pleroma.social@hacktivis.me>
Tue, 18 Aug 2020 19:02:33 +0000 (19:02 +0000)
Resolve "Make default image description blank"

Closes #2064

See merge request pleroma/pleroma!2899

21 files changed:
config/description.exs
docs/installation/freebsd_en.md [new file with mode: 0644]
installation/freebsd/rc.d/pleroma [new file with mode: 0755]
lib/pleroma/object/fetcher.ex
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/object_validator.ex
lib/pleroma/web/activity_pub/object_validators/answer_validator.ex
lib/pleroma/web/activity_pub/object_validators/audio_validator.ex [new file with mode: 0644]
lib/pleroma/web/activity_pub/object_validators/common_fixes.ex [new file with mode: 0644]
lib/pleroma/web/activity_pub/object_validators/create_note_validator.ex
lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex
lib/pleroma/web/activity_pub/object_validators/note_validator.ex
lib/pleroma/web/activity_pub/object_validators/question_validator.ex
lib/pleroma/web/activity_pub/object_validators/undo_validator.ex
lib/pleroma/web/activity_pub/side_effects.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
test/user_test.exs
test/web/activity_pub/transmogrifier/audio_handling_test.exs [new file with mode: 0644]
test/web/activity_pub/transmogrifier_test.exs
test/web/admin_api/controllers/admin_api_controller_test.exs
test/web/twitter_api/util_controller_test.exs

index 7734ff7a1b858efb0ec6747091914e07fe4a91b8..e27abf40f540b8ae7f93f259ababcf0d153dbb67 100644 (file)
@@ -1810,12 +1810,12 @@ config :pleroma, :config_description, [
           %{
             key: :enabled,
             type: :boolean,
-            description: "Enables invalidate media cache"
+            description: "Enables media cache object invalidation."
           },
           %{
             key: :provider,
             type: :module,
-            description: "Module which will be used to cache purge.",
+            description: "Module which will be used to purge objects from the cache.",
             suggestions: [
               Pleroma.Web.MediaProxy.Invalidation.Script,
               Pleroma.Web.MediaProxy.Invalidation.Http
diff --git a/docs/installation/freebsd_en.md b/docs/installation/freebsd_en.md
new file mode 100644 (file)
index 0000000..130d687
--- /dev/null
@@ -0,0 +1,210 @@
+# Installing on FreeBSD 
+
+This document was written for FreeBSD 12.1, but should be work on future releases.
+
+## Required software 
+
+This assumes the target system has `pkg(8)`.
+
+```
+# pkg install elixir postgresql12-server postgresql12-client postgresql12-contrib git-lite sudo nginx gmake acme.sh
+```
+
+Copy the rc.d scripts to the right directory:
+
+Setup the required services to automatically start at boot, using `sysrc(8)`.
+
+```
+# sysrc nginx_enable=YES
+# sysrc postgresql_enable=YES
+```
+
+## Initialize postgres
+
+```
+# service postgresql initdb
+# service postgresql start
+```
+
+## Configuring Pleroma
+
+Create a user for Pleroma:
+
+```
+# pw add user pleroma -m
+# echo 'export LC_ALL="en_US.UTF-8"' >> /home/pleroma/.profile
+# su -l pleroma
+```
+
+Clone the repository:
+
+```
+$ cd $HOME # Should be the same as /home/pleroma
+$ git clone -b stable https://git.pleroma.social/pleroma/pleroma.git
+```
+
+Configure Pleroma. Note that you need a domain name at this point:
+
+```
+$ cd /home/pleroma/pleroma
+$ mix deps.get # Enter "y" when asked to install Hex
+$ mix pleroma.instance gen # You will be asked a few questions here.
+$ cp config/generated_config.exs config/prod.secret.exs
+```
+
+Since Postgres is configured, we can now initialize the database. There should
+now be a file in `config/setup_db.psql` that makes this easier. Edit it, and
+*change the password* to a password of your choice. Make sure it is secure, since
+it'll be protecting your database. As root, you can now initialize the database:
+
+```
+# cd /home/pleroma/pleroma
+# sudo -Hu postgres -g postgres psql -f config/setup_db.psql
+```
+
+Postgres allows connections from all users without a password by default. To
+fix this, edit `/var/db/postgres/data12/pg_hba.conf`. Change every `trust` to
+`password`.
+
+Once this is done, restart Postgres with:
+```
+# service postgresql restart
+```
+
+Run the database migrations.
+
+Back as the pleroma user, run the following to implement any database migrations.
+
+```
+# su -l pleroma
+$ cd /home/pleroma/pleroma
+$ MIX_ENV=prod mix ecto.migrate
+```
+
+You will need to do this whenever you update with `git pull`:
+
+## Configuring acme.sh
+
+We'll be using acme.sh in Stateless Mode for TLS certificate renewal.
+
+First, as root, allow the user `acme` to have access to the acme log file, as follows:
+
+```
+# touch /var/log/acme.sh.log
+# chown acme:acme /var/log/acme.sh.log
+# chmod 600 /var/log/acme.sh.log
+```
+
+Next, obtain your account fingerprint:
+
+```
+# sudo -Hu acme -g acme acme.sh --register-account
+```
+
+You need to add the following to your nginx configuration for the server
+running on port 80:
+
+```
+  location ~ ^/\.well-known/acme-challenge/([-_a-zA-Z0-9]+)$ {
+    default_type text/plain;
+    return 200 "$1.6fXAG9VyG0IahirPEU2ZerUtItW2DHzDzD9wZaEKpqd";
+  }
+```
+
+Replace the string after after `$1.` with your fingerprint.
+
+Start nginx:
+
+```
+# service nginx start
+```
+
+It should now be possible to issue a cert (replace `example.com`
+with your domain name):
+
+```
+# sudo -Hu acme -g acme acme.sh --issue -d example.com --stateless
+```
+
+Let's add auto-renewal to `/etc/crontab`
+(replace `example.com` with your domain):
+
+```
+/usr/local/bin/sudo -Hu acme -g acme /usr/local/sbin/acme.sh -r -d example.com --stateless
+```
+
+### Configuring nginx
+
+FreeBSD's default nginx configuration does not contain an include directive, which is
+typically used for multiple sites. Therefore, you will need to first create the required
+directory as follows:
+
+
+```
+# mkdir -p /usr/local/etc/nginx/sites-available
+```
+
+Next, add an `include` directive to `/usr/local/etc/nginx/nginx.conf`, within the `http {}`
+block, as follows:
+
+
+```
+http {
+...
+       include /usr/local/etc/nginx/sites-available/*;
+}
+```
+
+As root, copy `/home/pleroma/pleroma/installation/pleroma.nginx` to
+`/usr/local/etc/nginx/sites-available/pleroma.nginx`.
+
+Edit the defaults of `/usr/local/etc/nginx/sites-available/pleroma.nginx`:
+
+* Change `ssl_trusted_certificate` to `/var/db/acme/certs/example.tld/example.tld.cer`.
+* Change `ssl_certificate` to `/var/db/acme/certs/example.tld/fullchain.cer`.
+* Change `ssl_certificate_key` to `/var/db/acme/certs/example.tld/example.tld.key`.
+* Change all references of `example.tld` to your instance's domain name.
+
+## Creating a startup script for Pleroma
+
+Pleroma will need to compile when it initially starts, which typically takes a longer
+period of time. Therefore, it is good practice to initially run pleroma from the
+command-line before utilizing the rc.d script. That is done as follows:
+
+```
+# su -l pleroma
+$ cd $HOME/pleroma
+$ MIX_ENV=prod mix phx.server
+```
+
+Copy the startup script to the correct location and make sure it's executable:
+
+```
+# cp /home/pleroma/pleroma/installation/freebsd/rc.d/pleroma /usr/local/etc/rc.d/pleroma
+# chmod +x /usr/local/etc/rc.d/pleroma
+```
+
+Update the `/etc/rc.conf` and start pleroma with the following commands:
+
+```
+# sysrc pleroma_enable=YES
+# service pleroma start
+```
+
+#### Create your first user
+
+If your instance is up and running, you can create your first user with administrative rights with the following task:
+
+```shell
+sudo -Hu pleroma MIX_ENV=prod mix pleroma.user new <username> <your@emailaddress> --admin
+```
+## Conclusion
+
+Restart nginx with `# service nginx restart` and you should be up and running.
+
+Make sure your time is in sync, or other instances will receive your posts with
+incorrect timestamps. You should have ntpd running.
+
+## Questions
+
+Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
diff --git a/installation/freebsd/rc.d/pleroma b/installation/freebsd/rc.d/pleroma
new file mode 100755 (executable)
index 0000000..f62aef1
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+# $FreeBSD$
+# PROVIDE: pleroma
+# REQUIRE: DAEMON postgresql
+# KEYWORD: shutdown
+
+# sudo -u pleroma MIX_ENV=prod elixir --erl \"-detached\" -S mix phx.server
+
+. /etc/rc.subr
+
+name=pleroma
+rcvar=pleroma_enable
+
+desc="Pleroma Social Media Platform"
+
+load_rc_config ${name}
+
+: ${pleroma_user:=pleroma}
+: ${pleroma_home:=$(getent passwd ${pleroma_user} | awk -F: '{print $6}')}
+: ${pleroma_chdir:="${pleroma_home}/pleroma"}
+: ${pleroma_env:="HOME=${pleroma_home} MIX_ENV=prod"}
+
+command=/usr/local/bin/elixir
+command_args="--erl \"-detached\" -S /usr/local/bin/mix phx.server"
+procname="*beam.smp"
+
+run_rc_command "$1"
index 3ff25118d5160c82b3f4922b29593f8f8eca5f28..6fdbc8efd175006f73d3bda0a2a8e180a5f06d21 100644 (file)
@@ -125,8 +125,8 @@ defmodule Pleroma.Object.Fetcher do
   defp prepare_activity_params(data) do
     %{
       "type" => "Create",
-      "to" => data["to"],
-      "cc" => data["cc"],
+      "to" => data["to"] || [],
+      "cc" => data["cc"] || [],
       # Should we seriously keep this attributedTo thing?
       "actor" => data["actor"] || data["attributedTo"],
       "object" => data
index ac065e9dcc6b86e1574d54d2eaaea36b426e36da..a9820affa075b56efcec71dd641da27b8aa12fc9 100644 (file)
@@ -1583,6 +1583,49 @@ defmodule Pleroma.User do
     |> update_and_set_cache()
   end
 
+  @spec purge_user_changeset(User.t()) :: Changeset.t()
+  def purge_user_changeset(user) do
+    # "Right to be forgotten"
+    # https://gdpr.eu/right-to-be-forgotten/
+    change(user, %{
+      bio: nil,
+      raw_bio: nil,
+      email: nil,
+      name: nil,
+      password_hash: nil,
+      keys: nil,
+      public_key: nil,
+      avatar: %{},
+      tags: [],
+      last_refreshed_at: nil,
+      last_digest_emailed_at: nil,
+      banner: %{},
+      background: %{},
+      note_count: 0,
+      follower_count: 0,
+      following_count: 0,
+      locked: false,
+      confirmation_pending: false,
+      password_reset_pending: false,
+      approval_pending: false,
+      registration_reason: nil,
+      confirmation_token: nil,
+      domain_blocks: [],
+      deactivated: true,
+      ap_enabled: false,
+      is_moderator: false,
+      is_admin: false,
+      mastofe_settings: nil,
+      mascot: nil,
+      emoji: %{},
+      pleroma_settings_store: %{},
+      fields: [],
+      raw_fields: [],
+      discoverable: false,
+      also_known_as: []
+    })
+  end
+
   def delete(users) when is_list(users) do
     for user <- users, do: delete(user)
   end
@@ -1610,7 +1653,7 @@ defmodule Pleroma.User do
 
       _ ->
         user
-        |> change(%{deactivated: true, email: nil})
+        |> purge_user_changeset()
         |> update_and_set_cache()
     end
   end
index 3f1dffe2b3700ccf82ff6c47a2ffd5b28e5ce486..d770ce1be37df31c2ed691cb362bbbe8a59b0c2a 100644 (file)
@@ -16,6 +16,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
   alias Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator
+  alias Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.BlockValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.ChatMessageValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.CreateChatMessageValidator
@@ -137,6 +138,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
     end
   end
 
+  def validate(%{"type" => "Audio"} = object, meta) do
+    with {:ok, object} <-
+           object
+           |> AudioValidator.cast_and_validate()
+           |> Ecto.Changeset.apply_action(:insert) do
+      object = stringify_keys(object)
+      {:ok, object, meta}
+    end
+  end
+
   def validate(%{"type" => "Answer"} = object, meta) do
     with {:ok, object} <-
            object
@@ -176,7 +187,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
         %{"type" => "Create", "object" => %{"type" => objtype} = object} = create_activity,
         meta
       )
-      when objtype in ["Question", "Answer"] do
+      when objtype in ~w[Question Answer Audio] do
     with {:ok, object_data} <- cast_and_apply(object),
          meta = Keyword.put(meta, :object_data, object_data |> stringify_keys),
          {:ok, create_activity} <-
@@ -210,6 +221,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
     AnswerValidator.cast_and_apply(object)
   end
 
+  def cast_and_apply(%{"type" => "Audio"} = object) do
+    AudioValidator.cast_and_apply(object)
+  end
+
   def cast_and_apply(o), do: {:error, {:validator_not_set, o}}
 
   # is_struct/1 isn't present in Elixir 1.8.x
index 3233676427012dc968c164729987d69052372164..b9fbaf4f68eba9074b1da53290270ff908de2890 100644 (file)
@@ -15,16 +15,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator do
 
   embedded_schema do
     field(:id, ObjectValidators.ObjectID, primary_key: true)
-    field(:to, {:array, :string}, default: [])
-    field(:cc, {:array, :string}, default: [])
-
-    # is this actually needed?
-    field(:bto, {:array, :string}, default: [])
-    field(:bcc, {:array, :string}, default: [])
-
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
+    field(:bto, ObjectValidators.Recipients, default: [])
+    field(:bcc, ObjectValidators.Recipients, default: [])
     field(:type, :string)
     field(:name, :string)
-    field(:inReplyTo, :string)
+    field(:inReplyTo, ObjectValidators.ObjectID)
     field(:attributedTo, ObjectValidators.ObjectID)
 
     # TODO: Remove actor on objects
diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_validator.ex
new file mode 100644 (file)
index 0000000..5d9bf34
--- /dev/null
@@ -0,0 +1,92 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioValidator do
+  use Ecto.Schema
+
+  alias Pleroma.EctoType.ActivityPub.ObjectValidators
+  alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
+  alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
+  alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
+
+  import Ecto.Changeset
+
+  @primary_key false
+  @derive Jason.Encoder
+
+  embedded_schema do
+    field(:id, ObjectValidators.ObjectID, primary_key: true)
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
+    field(:bto, ObjectValidators.Recipients, default: [])
+    field(:bcc, ObjectValidators.Recipients, default: [])
+    # TODO: Write type
+    field(:tag, {:array, :map}, default: [])
+    field(:type, :string)
+    field(:content, :string)
+    field(:context, :string)
+
+    # TODO: Remove actor on objects
+    field(:actor, ObjectValidators.ObjectID)
+
+    field(:attributedTo, ObjectValidators.ObjectID)
+    field(:summary, :string)
+    field(:published, ObjectValidators.DateTime)
+    # TODO: Write type
+    field(:emoji, :map, default: %{})
+    field(:sensitive, :boolean, default: false)
+    embeds_many(:attachment, AttachmentValidator)
+    field(:replies_count, :integer, default: 0)
+    field(:like_count, :integer, default: 0)
+    field(:announcement_count, :integer, default: 0)
+    field(:inReplyTo, :string)
+    field(:uri, ObjectValidators.Uri)
+    # short identifier for PleromaFE to group statuses by context
+    field(:context_id, :integer)
+
+    field(:likes, {:array, :string}, default: [])
+    field(:announcements, {:array, :string}, default: [])
+  end
+
+  def cast_and_apply(data) do
+    data
+    |> cast_data
+    |> apply_action(:insert)
+  end
+
+  def cast_and_validate(data) do
+    data
+    |> cast_data()
+    |> validate_data()
+  end
+
+  def cast_data(data) do
+    %__MODULE__{}
+    |> changeset(data)
+  end
+
+  defp fix(data) do
+    data
+    |> CommonFixes.fix_defaults()
+    |> CommonFixes.fix_attribution()
+  end
+
+  def changeset(struct, data) do
+    data = fix(data)
+
+    struct
+    |> cast(data, __schema__(:fields) -- [:attachment])
+    |> cast_embed(:attachment)
+  end
+
+  def validate_data(data_cng) do
+    data_cng
+    |> validate_inclusion(:type, ["Audio"])
+    |> validate_required([:id, :actor, :attributedTo, :type, :context])
+    |> CommonValidations.validate_any_presence([:cc, :to])
+    |> CommonValidations.validate_fields_match([:actor, :attributedTo])
+    |> CommonValidations.validate_actor_presence()
+    |> CommonValidations.validate_host_match()
+  end
+end
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex b/lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
new file mode 100644 (file)
index 0000000..721749d
--- /dev/null
@@ -0,0 +1,22 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
+  alias Pleroma.Web.ActivityPub.Utils
+
+  # based on Pleroma.Web.ActivityPub.Utils.lazy_put_objects_defaults
+  def fix_defaults(data) do
+    %{data: %{"id" => context}, id: context_id} =
+      Utils.create_context(data["context"] || data["conversation"])
+
+    data
+    |> Map.put_new("context", context)
+    |> Map.put_new("context_id", context_id)
+  end
+
+  def fix_attribution(data) do
+    data
+    |> Map.put_new("actor", data["attributedTo"])
+  end
+end
index 316bd0c073a248b6395d5b7431a0da3531086761..9b9743c4ae7fa5a049f880bc15cfd1854317bdec 100644 (file)
@@ -16,11 +16,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateNoteValidator do
     field(:id, ObjectValidators.ObjectID, primary_key: true)
     field(:actor, ObjectValidators.ObjectID)
     field(:type, :string)
-    field(:to, {:array, :string})
-    field(:cc, {:array, :string})
-    field(:bto, {:array, :string}, default: [])
-    field(:bcc, {:array, :string}, default: [])
-
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
+    field(:bto, ObjectValidators.Recipients, default: [])
+    field(:bcc, ObjectValidators.Recipients, default: [])
     embeds_one(:object, NoteValidator)
   end
 
index a543af1f82c598dea8824cb9358223d4ac8678ed..336c92d354593dcd5b8884f8688e0db2824d49c9 100644 (file)
@@ -20,8 +20,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
     field(:actor, ObjectValidators.ObjectID)
     field(:context, :string)
     field(:content, :string)
-    field(:to, {:array, :string}, default: [])
-    field(:cc, {:array, :string}, default: [])
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
   end
 
   def cast_and_validate(data) do
index a65fe23549ab2aec3330c859eb5a3618315f32a3..14ae29cb6a7e58151ed59a9eee64e90d8ad92603 100644 (file)
@@ -13,10 +13,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
 
   embedded_schema do
     field(:id, ObjectValidators.ObjectID, primary_key: true)
-    field(:to, {:array, :string}, default: [])
-    field(:cc, {:array, :string}, default: [])
-    field(:bto, {:array, :string}, default: [])
-    field(:bcc, {:array, :string}, default: [])
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
+    field(:bto, ObjectValidators.Recipients, default: [])
+    field(:bcc, ObjectValidators.Recipients, default: [])
     # TODO: Write type
     field(:tag, {:array, :map}, default: [])
     field(:type, :string)
@@ -34,7 +34,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
     field(:replies_count, :integer, default: 0)
     field(:like_count, :integer, default: 0)
     field(:announcement_count, :integer, default: 0)
-    field(:inReplyTo, :string)
+    field(:inReplyTo, ObjectValidators.ObjectID)
     field(:uri, ObjectValidators.Uri)
 
     field(:likes, {:array, :string}, default: [])
index f47acf606aabd89ddc756f83176db4f4db48e628..a7ca42b2fa3c71047f95edf18a45a76207085c14 100644 (file)
@@ -7,9 +7,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
 
   alias Pleroma.EctoType.ActivityPub.ObjectValidators
   alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
+  alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
   alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
-  alias Pleroma.Web.ActivityPub.Utils
 
   import Ecto.Changeset
 
@@ -19,10 +19,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
   # Extends from NoteValidator
   embedded_schema do
     field(:id, ObjectValidators.ObjectID, primary_key: true)
-    field(:to, {:array, :string}, default: [])
-    field(:cc, {:array, :string}, default: [])
-    field(:bto, {:array, :string}, default: [])
-    field(:bcc, {:array, :string}, default: [])
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
+    field(:bto, ObjectValidators.Recipients, default: [])
+    field(:bcc, ObjectValidators.Recipients, default: [])
     # TODO: Write type
     field(:tag, {:array, :map}, default: [])
     field(:type, :string)
@@ -42,7 +42,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
     field(:replies_count, :integer, default: 0)
     field(:like_count, :integer, default: 0)
     field(:announcement_count, :integer, default: 0)
-    field(:inReplyTo, :string)
+    field(:inReplyTo, ObjectValidators.ObjectID)
     field(:uri, ObjectValidators.Uri)
     # short identifier for PleromaFE to group statuses by context
     field(:context_id, :integer)
@@ -81,27 +81,11 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
     end
   end
 
-  # based on Pleroma.Web.ActivityPub.Utils.lazy_put_objects_defaults
-  defp fix_defaults(data) do
-    %{data: %{"id" => context}, id: context_id} =
-      Utils.create_context(data["context"] || data["conversation"])
-
-    data
-    |> Map.put_new_lazy("published", &Utils.make_date/0)
-    |> Map.put_new("context", context)
-    |> Map.put_new("context_id", context_id)
-  end
-
-  defp fix_attribution(data) do
-    data
-    |> Map.put_new("actor", data["attributedTo"])
-  end
-
   defp fix(data) do
     data
-    |> fix_attribution()
+    |> CommonFixes.fix_defaults()
+    |> CommonFixes.fix_attribution()
     |> fix_closed()
-    |> fix_defaults()
   end
 
   def changeset(struct, data) do
@@ -117,7 +101,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
   def validate_data(data_cng) do
     data_cng
     |> validate_inclusion(:type, ["Question"])
-    |> validate_required([:id, :actor, :attributedTo, :type, :context])
+    |> validate_required([:id, :actor, :attributedTo, :type, :context, :context_id])
     |> CommonValidations.validate_any_presence([:cc, :to])
     |> CommonValidations.validate_fields_match([:actor, :attributedTo])
     |> CommonValidations.validate_actor_presence()
index e8d2d39c124c9f819bd2ea0a654b0783b80ad61f..8cae94467429afe8b4a0213545bd074fb87b4cb8 100644 (file)
@@ -18,8 +18,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator do
     field(:type, :string)
     field(:object, ObjectValidators.ObjectID)
     field(:actor, ObjectValidators.ObjectID)
-    field(:to, {:array, :string}, default: [])
-    field(:cc, {:array, :string}, default: [])
+    field(:to, ObjectValidators.Recipients, default: [])
+    field(:cc, ObjectValidators.Recipients, default: [])
   end
 
   def cast_and_validate(data) do
index bcd6fd2fb1d55b10b31f37aa9586aa655dad33bc..3dc66c60b838e713ed252ed43ce3d17a84acab1b 100644 (file)
@@ -340,7 +340,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
     end
   end
 
-  def handle_object_creation(%{"type" => "Question"} = object, meta) do
+  def handle_object_creation(%{"type" => objtype} = object, meta)
+      when objtype in ~w[Audio Question] do
     with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
       {:ok, object, meta}
     end
index 544f3f3b67c880ba2e4cb972a15edf704de7f91a..6be17e0eda7b30d8076b7489d4f04be27941791b 100644 (file)
@@ -461,7 +461,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
         %{"type" => "Create", "object" => %{"type" => objtype} = object} = data,
         options
       )
-      when objtype in ["Article", "Event", "Note", "Video", "Page", "Audio"] do
+      when objtype in ~w{Article Event Note Video Page} do
     actor = Containment.get_actor(data)
 
     with nil <- Activity.get_create_by_object_ap_id(object["id"]),
@@ -555,7 +555,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
         %{"type" => "Create", "object" => %{"type" => objtype}} = data,
         _options
       )
-      when objtype in ["Question", "Answer", "ChatMessage"] do
+      when objtype in ~w{Question Answer ChatMessage Audio} do
     with {:ok, %User{}} <- ObjectValidator.fetch_actor(data),
          {:ok, activity, _} <- Pipeline.common_pipeline(data, local: false) do
       {:ok, activity}
index b4740589593bb8e673b6914ac63e51102ba4e566..3cf248659c40f962342069df2014f8bbd460829b 100644 (file)
@@ -1417,7 +1417,6 @@ defmodule Pleroma.UserTest do
 
   test "delete/1 when approval is pending deletes the user" do
     user = insert(:user, approval_pending: true)
-    {:ok, user: user}
 
     {:ok, job} = User.delete(user)
     {:ok, _} = ObanHelpers.perform(job)
@@ -1426,6 +1425,85 @@ defmodule Pleroma.UserTest do
     refute User.get_by_id(user.id)
   end
 
+  test "delete/1 purges a user when they wouldn't be fully deleted" do
+    user =
+      insert(:user, %{
+        bio: "eyy lmao",
+        name: "qqqqqqq",
+        password_hash: "pdfk2$1b3n159001",
+        keys: "RSA begin buplic key",
+        public_key: "--PRIVATE KEYE--",
+        avatar: %{"a" => "b"},
+        tags: ["qqqqq"],
+        banner: %{"a" => "b"},
+        background: %{"a" => "b"},
+        note_count: 9,
+        follower_count: 9,
+        following_count: 9001,
+        locked: true,
+        confirmation_pending: true,
+        password_reset_pending: true,
+        approval_pending: true,
+        registration_reason: "ahhhhh",
+        confirmation_token: "qqqq",
+        domain_blocks: ["lain.com"],
+        deactivated: true,
+        ap_enabled: true,
+        is_moderator: true,
+        is_admin: true,
+        mastofe_settings: %{"a" => "b"},
+        mascot: %{"a" => "b"},
+        emoji: %{"a" => "b"},
+        pleroma_settings_store: %{"q" => "x"},
+        fields: [%{"gg" => "qq"}],
+        raw_fields: [%{"gg" => "qq"}],
+        discoverable: true,
+        also_known_as: ["https://lol.olo/users/loll"]
+      })
+
+    {:ok, job} = User.delete(user)
+    {:ok, _} = ObanHelpers.perform(job)
+    user = User.get_by_id(user.id)
+
+    assert %User{
+             bio: nil,
+             raw_bio: nil,
+             email: nil,
+             name: nil,
+             password_hash: nil,
+             keys: nil,
+             public_key: nil,
+             avatar: %{},
+             tags: [],
+             last_refreshed_at: nil,
+             last_digest_emailed_at: nil,
+             banner: %{},
+             background: %{},
+             note_count: 0,
+             follower_count: 0,
+             following_count: 0,
+             locked: false,
+             confirmation_pending: false,
+             password_reset_pending: false,
+             approval_pending: false,
+             registration_reason: nil,
+             confirmation_token: nil,
+             domain_blocks: [],
+             deactivated: true,
+             ap_enabled: false,
+             is_moderator: false,
+             is_admin: false,
+             mastofe_settings: nil,
+             mascot: nil,
+             emoji: %{},
+             pleroma_settings_store: %{},
+             fields: [],
+             raw_fields: [],
+             discoverable: false,
+             also_known_as: []
+           } = user
+  end
+
   test "get_public_key_for_ap_id fetches a user that's not in the db" do
     assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
   end
diff --git a/test/web/activity_pub/transmogrifier/audio_handling_test.exs b/test/web/activity_pub/transmogrifier/audio_handling_test.exs
new file mode 100644 (file)
index 0000000..c74a9c4
--- /dev/null
@@ -0,0 +1,45 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.Transmogrifier.AudioHandlingTest do
+  use Oban.Testing, repo: Pleroma.Repo
+  use Pleroma.DataCase
+
+  alias Pleroma.Activity
+  alias Pleroma.Object
+  alias Pleroma.Web.ActivityPub.Transmogrifier
+
+  import Pleroma.Factory
+
+  test "it works for incoming listens" do
+    _user = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
+
+    data = %{
+      "@context" => "https://www.w3.org/ns/activitystreams",
+      "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+      "cc" => [],
+      "type" => "Listen",
+      "id" => "http://mastodon.example.org/users/admin/listens/1234/activity",
+      "actor" => "http://mastodon.example.org/users/admin",
+      "object" => %{
+        "type" => "Audio",
+        "id" => "http://mastodon.example.org/users/admin/listens/1234",
+        "attributedTo" => "http://mastodon.example.org/users/admin",
+        "title" => "lain radio episode 1",
+        "artist" => "lain",
+        "album" => "lain radio",
+        "length" => 180_000
+      }
+    }
+
+    {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+    object = Object.normalize(activity)
+
+    assert object.data["title"] == "lain radio episode 1"
+    assert object.data["artist"] == "lain"
+    assert object.data["album"] == "lain radio"
+    assert object.data["length"] == 180_000
+  end
+end
index 0dd4e6e47b00f52ef393b4642585a334c22e0bef..3fa41b0c71d088b548bcb2bbc0ff490e939e0a3c 100644 (file)
@@ -225,35 +225,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert Enum.at(object.data["tag"], 2) == "moo"
     end
 
-    test "it works for incoming listens" do
-      data = %{
-        "@context" => "https://www.w3.org/ns/activitystreams",
-        "to" => ["https://www.w3.org/ns/activitystreams#Public"],
-        "cc" => [],
-        "type" => "Listen",
-        "id" => "http://mastodon.example.org/users/admin/listens/1234/activity",
-        "actor" => "http://mastodon.example.org/users/admin",
-        "object" => %{
-          "type" => "Audio",
-          "id" => "http://mastodon.example.org/users/admin/listens/1234",
-          "attributedTo" => "http://mastodon.example.org/users/admin",
-          "title" => "lain radio episode 1",
-          "artist" => "lain",
-          "album" => "lain radio",
-          "length" => 180_000
-        }
-      }
-
-      {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
-
-      object = Object.normalize(activity)
-
-      assert object.data["title"] == "lain radio episode 1"
-      assert object.data["artist"] == "lain"
-      assert object.data["album"] == "lain radio"
-      assert object.data["length"] == 180_000
-    end
-
     test "it works for incoming notices with contentMap" do
       data =
         File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()
index 66d4b1ef36bf03666cf32f4ad9610738aa479be8..2eb698807118ab78f3b6464458c79a3823c56cf8 100644 (file)
@@ -155,13 +155,30 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
 
   describe "DELETE /api/pleroma/admin/users" do
     test "single user", %{admin: admin, conn: conn} do
-      user = insert(:user)
       clear_config([:instance, :federating], true)
 
+      user =
+        insert(:user,
+          avatar: %{"url" => [%{"href" => "https://someurl"}]},
+          banner: %{"url" => [%{"href" => "https://somebanner"}]},
+          bio: "Hello world!",
+          name: "A guy"
+        )
+
+      # Create some activities to check they got deleted later
+      follower = insert(:user)
+      {:ok, _} = CommonAPI.post(user, %{status: "test"})
+      {:ok, _, _, _} = CommonAPI.follow(user, follower)
+      {:ok, _, _, _} = CommonAPI.follow(follower, user)
+      user = Repo.get(User, user.id)
+      assert user.note_count == 1
+      assert user.follower_count == 1
+      assert user.following_count == 1
       refute user.deactivated
 
       with_mock Pleroma.Web.Federator,
-        publish: fn _ -> nil end do
+        publish: fn _ -> nil end,
+        perform: fn _, _ -> nil end do
         conn =
           conn
           |> put_req_header("accept", "application/json")
@@ -181,6 +198,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
         user = Repo.get(User, user.id)
         assert user.deactivated
 
+        assert user.avatar == %{}
+        assert user.banner == %{}
+        assert user.note_count == 0
+        assert user.follower_count == 0
+        assert user.following_count == 0
+        assert user.bio == nil
+        assert user.name == nil
+
         assert called(Pleroma.Web.Federator.publish(:_))
       end
     end
index 109c1e63766f8ae68837629f45e9832c5dcc3941..354d77b562dff4478febf9f695ed1fb38e666191 100644 (file)
@@ -586,10 +586,16 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
       end
     end
 
-    test "with proper permissions and valid password", %{conn: conn} do
+    test "with proper permissions and valid password", %{conn: conn, user: user} do
       conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"})
-
+      ObanHelpers.perform_all()
       assert json_response(conn, 200) == %{"status" => "success"}
+
+      user = User.get_by_id(user.id)
+      assert user.deactivated == true
+      assert user.name == nil
+      assert user.bio == nil
+      assert user.password_hash == nil
     end
   end
 end