summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--config/config.exs14
-rw-r--r--config/description.exs42
-rw-r--r--config/test.exs2
-rw-r--r--docs/clients.md7
-rw-r--r--docs/configuration/cheatsheet.md10
-rw-r--r--lib/pleroma/config.ex41
-rw-r--r--lib/pleroma/following_relationship.ex6
-rw-r--r--lib/pleroma/user.ex21
-rw-r--r--lib/pleroma/user/welcome_chat_message.ex45
-rw-r--r--lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex4
-rw-r--r--lib/pleroma/web/activity_pub/mrf/object_age_policy.ex13
-rw-r--r--lib/pleroma/web/activity_pub/mrf/simple_policy.ex31
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/common_validations.ex13
-rw-r--r--lib/pleroma/web/rich_media/helpers.ex21
-rw-r--r--lib/pleroma/web/rich_media/parser.ex20
-rw-r--r--lib/pleroma/web/rich_media/parsers/oembed_parser.ex2
-rw-r--r--lib/pleroma/web/templates/layout/app.html.eex2
-rw-r--r--mix.exs3
-rw-r--r--priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs19
-rw-r--r--priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs7
-rw-r--r--test/config_test.exs46
-rw-r--r--test/report_note_test.exs16
-rw-r--r--test/support/factory.ex24
-rw-r--r--test/support/helpers.ex14
-rw-r--r--test/tasks/app_test.exs6
-rw-r--r--test/user/welcome_chat_massage_test.exs35
-rw-r--r--test/user_test.exs58
-rw-r--r--test/web/activity_pub/mrf/activity_expiration_policy_test.exs7
-rw-r--r--test/web/activity_pub/mrf/object_age_policy_test.exs42
-rw-r--r--test/web/activity_pub/mrf/simple_policy_test.exs60
-rw-r--r--test/web/activity_pub/transmogrifier/chat_message_test.exs18
-rw-r--r--test/web/activity_pub/transmogrifier_test.exs8
-rw-r--r--test/web/common_api/common_api_test.exs5
-rw-r--r--test/web/mastodon_api/controllers/account_controller_test.exs29
-rw-r--r--test/web/mastodon_api/mastodon_api_test.exs3
-rw-r--r--test/web/oauth/app_test.exs11
37 files changed, 639 insertions, 69 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 129c269aa..de017e30a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -49,6 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
+- Configuration: Added a blacklist for email servers.
- Chats: Added `accepts_chat_messages` field to user, exposed in APIs and federation.
- Chats: Added support for federated chats. For details, see the docs.
- ActivityPub: Added support for existing AP ids for instances migrated from Mastodon.
@@ -69,7 +70,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Support for viewing instances favicons next to posts and accounts
- Added Pleroma.Upload.Filter.Exiftool as an alternate EXIF stripping mechanism targeting GPS/location metadata.
- "By approval" registrations mode.
-- Configuration: Added `:welcome` settings for the welcome message to newly registered users.
+- Configuration: Added `:welcome` settings for the welcome message to newly registered users. You can send a welcome message as a direct message, chat or email.
- Ability to hide favourites and emoji reactions in the API with `[:instance, :show_reactions]` config.
<details>
diff --git a/config/config.exs b/config/config.exs
index d31208c25..933a899ab 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -261,6 +261,11 @@ config :pleroma, :welcome,
sender_nickname: nil,
message: nil
],
+ chat_message: [
+ enabled: false,
+ sender_nickname: nil,
+ message: nil
+ ],
email: [
enabled: false,
sender: nil,
@@ -374,6 +379,7 @@ config :pleroma, :mrf_simple,
federated_timeline_removal: [],
report_removal: [],
reject: [],
+ followers_only: [],
accept: [],
avatar_removal: [],
banner_removal: [],
@@ -392,8 +398,9 @@ config :pleroma, :mrf_vocabulary,
accept: [],
reject: []
+# threshold of 7 days
config :pleroma, :mrf_object_age,
- threshold: 172_800,
+ threshold: 604_800,
actions: [:delist, :strip_followers]
config :pleroma, :rich_media,
@@ -509,7 +516,8 @@ config :pleroma, Pleroma.User,
"user_exists",
"users",
"web"
- ]
+ ],
+ email_blacklist: []
config :pleroma, Oban,
repo: Pleroma.Repo,
@@ -719,7 +727,7 @@ config :pleroma, :restrict_unauthenticated,
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: false
config :pleroma, :mrf,
- policies: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
+ policies: Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy,
transparency: true,
transparency_exclusions: []
diff --git a/config/description.exs b/config/description.exs
index 11fbe0d78..d823812fb 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -998,6 +998,35 @@ config :pleroma, :config_description, [
]
},
%{
+ group: :chat_message,
+ type: :group,
+ descpiption: "Chat message settings",
+ children: [
+ %{
+ key: :enabled,
+ type: :boolean,
+ description: "Enables sends chat message for new user after registration"
+ },
+ %{
+ key: :message,
+ type: :string,
+ description:
+ "A message that will be sent to a newly registered users as a chat message",
+ suggestions: [
+ "Hello, welcome on board!"
+ ]
+ },
+ %{
+ key: :sender_nickname,
+ type: :string,
+ description: "The nickname of the local user that sends the welcome message",
+ suggestions: [
+ "lain"
+ ]
+ }
+ ]
+ },
+ %{
group: :email,
type: :group,
descpiption: "Email message settings",
@@ -1543,6 +1572,12 @@ config :pleroma, :config_description, [
suggestions: ["example.com", "*.example.com"]
},
%{
+ key: :followers_only,
+ type: {:list, :string},
+ description: "Force posts from the given instances to be visible by followers only",
+ suggestions: ["example.com", "*.example.com"]
+ },
+ %{
key: :report_removal,
type: {:list, :string},
description: "List of instances to reject reports from",
@@ -3021,6 +3056,7 @@ config :pleroma, :config_description, [
%{
key: :restricted_nicknames,
type: {:list, :string},
+ description: "List of nicknames users may not register with.",
suggestions: [
".well-known",
"~",
@@ -3053,6 +3089,12 @@ config :pleroma, :config_description, [
"users",
"web"
]
+ },
+ %{
+ key: :email_blacklist,
+ type: {:list, :string},
+ description: "List of email domains users may not register with.",
+ suggestions: ["mailinator.com", "maildrop.cc"]
}
]
},
diff --git a/config/test.exs b/config/test.exs
index db0655e73..413c7f0b9 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -120,6 +120,8 @@ config :pleroma, Pleroma.Uploaders.S3,
config :tzdata, :autoupdate, :disabled
+config :pleroma, :mrf, policies: []
+
if File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs"
else
diff --git a/docs/clients.md b/docs/clients.md
index ea751637e..2a42c659f 100644
--- a/docs/clients.md
+++ b/docs/clients.md
@@ -75,6 +75,13 @@ Feel free to contact us to be added to this list!
- Platform: Android, iOS
- Features: No Streaming
+### Indigenous
+- Homepage: <https://indigenous.realize.be/>
+- Source Code: <https://github.com/swentel/indigenous-android/>
+- Contact: [@realize.be@realize.be](@realize.be@realize.be)
+- Platforms: Android
+- Features: No Streaming
+
## Alternative Web Interfaces
### Brutaldon
- Homepage: <https://jfm.carcosa.net/projects/software/brutaldon/>
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 9c768abef..f23cf4fe4 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -69,6 +69,10 @@ To add configuration to your config file, you can copy it from the base config.
* `enabled`: Enables the send a direct message to a newly registered user. Defaults to `false`.
* `sender_nickname`: The nickname of the local user that sends the welcome message.
* `message`: A message that will be send to a newly registered users as a direct message.
+* `chat_message`: - welcome message sent as a chat message.
+ * `enabled`: Enables the send a chat message to a newly registered user. Defaults to `false`.
+ * `sender_nickname`: The nickname of the local user that sends the welcome message.
+ * `message`: A message that will be send to a newly registered users as a chat message.
* `email`: - welcome message sent as a email.
* `enabled`: Enables the send a welcome email to a newly registered user. Defaults to `false`.
* `sender`: The email address or tuple with `{nickname, email}` that will use as sender to the welcome email.
@@ -125,6 +129,7 @@ To add configuration to your config file, you can copy it from the base config.
* `federated_timeline_removal`: List of instances to remove from Federated (aka The Whole Known Network) Timeline.
* `reject`: List of instances to reject any activities from.
* `accept`: List of instances to accept any activities from.
+* `followers_only`: List of instances to decrease post visibility to only the followers, including for DM mentions.
* `report_removal`: List of instances to reject reports from.
* `avatar_removal`: List of instances to strip avatars from.
* `banner_removal`: List of instances to strip banners from.
@@ -202,6 +207,11 @@ config :pleroma, :mrf_user_allowlist, %{
* `sign_object_fetches`: Sign object fetches with HTTP signatures
* `authorized_fetch_mode`: Require HTTP signatures for AP fetches
+## Pleroma.User
+
+* `restricted_nicknames`: List of nicknames users may not register with.
+* `email_blacklist`: List of email domains users may not register with.
+
## Pleroma.ScheduledActivity
* `daily_user_limit`: the number of scheduled activities a user is allowed to create in a single day (Default: `25`)
diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex
index cc80deff5..a8329cc1e 100644
--- a/lib/pleroma/config.ex
+++ b/lib/pleroma/config.ex
@@ -11,12 +11,10 @@ defmodule Pleroma.Config do
def get([key], default), do: get(key, default)
- def get([parent_key | keys], default) do
- case :pleroma
- |> Application.get_env(parent_key)
- |> get_in(keys) do
- nil -> default
- any -> any
+ def get([_ | _] = path, default) do
+ case fetch(path) do
+ {:ok, value} -> value
+ :error -> default
end
end
@@ -34,6 +32,24 @@ defmodule Pleroma.Config do
end
end
+ def fetch(key) when is_atom(key), do: fetch([key])
+
+ def fetch([root_key | keys]) do
+ Enum.reduce_while(keys, Application.fetch_env(:pleroma, root_key), fn
+ key, {:ok, config} when is_map(config) or is_list(config) ->
+ case Access.fetch(config, key) do
+ :error ->
+ {:halt, :error}
+
+ value ->
+ {:cont, value}
+ end
+
+ _key, _config ->
+ {:halt, :error}
+ end)
+ end
+
def put([key], value), do: put(key, value)
def put([parent_key | keys], value) do
@@ -50,12 +66,15 @@ defmodule Pleroma.Config do
def delete([key]), do: delete(key)
- def delete([parent_key | keys]) do
- {_, parent} =
- Application.get_env(:pleroma, parent_key)
- |> get_and_update_in(keys, fn _ -> :pop end)
+ def delete([parent_key | keys] = path) do
+ with {:ok, _} <- fetch(path) do
+ {_, parent} =
+ parent_key
+ |> get()
+ |> get_and_update_in(keys, fn _ -> :pop end)
- Application.put_env(:pleroma, parent_key, parent)
+ Application.put_env(:pleroma, parent_key, parent)
+ end
end
def delete(key) do
diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex
index c2020d30a..83b366dd4 100644
--- a/lib/pleroma/following_relationship.ex
+++ b/lib/pleroma/following_relationship.ex
@@ -95,7 +95,11 @@ defmodule Pleroma.FollowingRelationship do
|> where([r], r.state == ^:follow_accept)
end
- def followers_ap_ids(%User{} = user, from_ap_ids \\ nil) do
+ def followers_ap_ids(user, from_ap_ids \\ nil)
+
+ def followers_ap_ids(_, []), do: []
+
+ def followers_ap_ids(%User{} = user, from_ap_ids) do
query =
user
|> followers_query()
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index dcf6ebee2..09e606b37 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -676,10 +676,19 @@ defmodule Pleroma.User do
|> validate_required([:name, :nickname, :password, :password_confirmation])
|> validate_confirmation(:password)
|> unique_constraint(:email)
+ |> validate_format(:email, @email_regex)
+ |> validate_change(:email, fn :email, email ->
+ valid? =
+ Config.get([User, :email_blacklist])
+ |> Enum.all?(fn blacklisted_domain ->
+ !String.ends_with?(email, ["@" <> blacklisted_domain, "." <> blacklisted_domain])
+ end)
+
+ if valid?, do: [], else: [email: "Invalid email"]
+ end)
|> unique_constraint(:nickname)
|> validate_exclusion(:nickname, Config.get([User, :restricted_nicknames]))
|> validate_format(:nickname, local_nickname_regex())
- |> validate_format(:email, @email_regex)
|> validate_length(:bio, max: bio_limit)
|> validate_length(:name, min: 1, max: name_limit)
|> validate_length(:registration_reason, max: reason_limit)
@@ -734,6 +743,7 @@ defmodule Pleroma.User do
{:ok, user} <- set_cache(user),
{:ok, _} <- send_welcome_email(user),
{:ok, _} <- send_welcome_message(user),
+ {:ok, _} <- send_welcome_chat_message(user),
{:ok, _} <- try_send_confirmation_email(user) do
{:ok, user}
end
@@ -748,6 +758,15 @@ defmodule Pleroma.User do
end
end
+ def send_welcome_chat_message(user) do
+ if User.WelcomeChatMessage.enabled?() do
+ User.WelcomeChatMessage.post_message(user)
+ {:ok, :enqueued}
+ else
+ {:ok, :noop}
+ end
+ end
+
def send_welcome_email(%User{email: email} = user) when is_binary(email) do
if User.WelcomeEmail.enabled?() do
User.WelcomeEmail.send_email(user)
diff --git a/lib/pleroma/user/welcome_chat_message.ex b/lib/pleroma/user/welcome_chat_message.ex
new file mode 100644
index 000000000..3e7d1f424
--- /dev/null
+++ b/lib/pleroma/user/welcome_chat_message.ex
@@ -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.User.WelcomeChatMessage do
+ alias Pleroma.Config
+ alias Pleroma.User
+ alias Pleroma.Web.CommonAPI
+
+ @spec enabled?() :: boolean()
+ def enabled?, do: Config.get([:welcome, :chat_message, :enabled], false)
+
+ @spec post_message(User.t()) :: {:ok, Pleroma.Activity.t() | nil}
+ def post_message(user) do
+ [:welcome, :chat_message, :sender_nickname]
+ |> Config.get(nil)
+ |> fetch_sender()
+ |> do_post(user, welcome_message())
+ end
+
+ defp do_post(%User{} = sender, recipient, message)
+ when is_binary(message) do
+ CommonAPI.post_chat_message(
+ sender,
+ recipient,
+ message
+ )
+ end
+
+ defp do_post(_sender, _recipient, _message), do: {:ok, nil}
+
+ defp fetch_sender(nickname) when is_binary(nickname) do
+ with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
+ user
+ else
+ _ -> nil
+ end
+ end
+
+ defp fetch_sender(_), do: nil
+
+ defp welcome_message do
+ Config.get([:welcome, :chat_message, :message], nil)
+ end
+end
diff --git a/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex b/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex
index 8e47f1e02..7b4c78e0f 100644
--- a/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/activity_expiration_policy.ex
@@ -21,8 +21,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy do
@impl true
def describe, do: {:ok, %{}}
- defp local?(%{"id" => id}) do
- String.starts_with?(id, Pleroma.Web.Endpoint.url())
+ defp local?(%{"actor" => actor}) do
+ String.starts_with?(actor, Pleroma.Web.Endpoint.url())
end
defp note?(activity) do
diff --git a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
index 5f111c72f..d45d2d7e3 100644
--- a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex
@@ -37,8 +37,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
defp check_delist(message, actions) do
if :delist in actions do
with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do
- to = List.delete(message["to"], Pleroma.Constants.as_public()) ++ [user.follower_address]
- cc = List.delete(message["cc"], user.follower_address) ++ [Pleroma.Constants.as_public()]
+ to =
+ List.delete(message["to"] || [], Pleroma.Constants.as_public()) ++
+ [user.follower_address]
+
+ cc =
+ List.delete(message["cc"] || [], user.follower_address) ++
+ [Pleroma.Constants.as_public()]
message =
message
@@ -58,8 +63,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
defp check_strip_followers(message, actions) do
if :strip_followers in actions do
with %User{} = user <- User.get_cached_by_ap_id(message["actor"]) do
- to = List.delete(message["to"], user.follower_address)
- cc = List.delete(message["cc"], user.follower_address)
+ to = List.delete(message["to"] || [], user.follower_address)
+ cc = List.delete(message["cc"] || [], user.follower_address)
message =
message
diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
index b77b8c7b4..bb193475a 100644
--- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
@behaviour Pleroma.Web.ActivityPub.MRF
alias Pleroma.Config
+ alias Pleroma.FollowingRelationship
alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF
@@ -108,6 +109,35 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
{:ok, object}
end
+ defp intersection(list1, list2) do
+ list1 -- list1 -- list2
+ end
+
+ defp check_followers_only(%{host: actor_host} = _actor_info, object) do
+ followers_only =
+ Config.get([:mrf_simple, :followers_only])
+ |> MRF.subdomains_regex()
+
+ object =
+ with true <- MRF.subdomain_match?(followers_only, actor_host),
+ user <- User.get_cached_by_ap_id(object["actor"]) do
+ # Don't use Map.get/3 intentionally, these must not be nil
+ fixed_to = object["to"] || []
+ fixed_cc = object["cc"] || []
+
+ to = FollowingRelationship.followers_ap_ids(user, fixed_to)
+ cc = FollowingRelationship.followers_ap_ids(user, fixed_cc)
+
+ object
+ |> Map.put("to", intersection([user.follower_address | to], fixed_to))
+ |> Map.put("cc", intersection([user.follower_address | cc], fixed_cc))
+ else
+ _ -> object
+ end
+
+ {:ok, object}
+ end
+
defp check_report_removal(%{host: actor_host} = _actor_info, %{"type" => "Flag"} = object) do
report_removal =
Config.get([:mrf_simple, :report_removal])
@@ -174,6 +204,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
{:ok, object} <- check_media_removal(actor_info, object),
{:ok, object} <- check_media_nsfw(actor_info, object),
{:ok, object} <- check_ftl_removal(actor_info, object),
+ {:ok, object} <- check_followers_only(actor_info, object),
{:ok, object} <- check_report_removal(actor_info, object) do
{:ok, object}
else
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex
index aeef31945..bd46f8034 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_validations.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_validations.ex
@@ -34,10 +34,15 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do
cng
|> validate_change(field_name, fn field_name, actor ->
- if User.get_cached_by_ap_id(actor) do
- []
- else
- [{field_name, "can't find user"}]
+ case User.get_cached_by_ap_id(actor) do
+ %User{deactivated: true} ->
+ [{field_name, "user is deactivated"}]
+
+ %User{} ->
+ []
+
+ _ ->
+ [{field_name, "can't find user"}]
end
end)
end
diff --git a/lib/pleroma/web/rich_media/helpers.ex b/lib/pleroma/web/rich_media/helpers.ex
index 5c7daf1a5..6210f2c5a 100644
--- a/lib/pleroma/web/rich_media/helpers.ex
+++ b/lib/pleroma/web/rich_media/helpers.ex
@@ -9,6 +9,11 @@ defmodule Pleroma.Web.RichMedia.Helpers do
alias Pleroma.Object
alias Pleroma.Web.RichMedia.Parser
+ @rich_media_options [
+ pool: :media,
+ max_body: 2_000_000
+ ]
+
@spec validate_page_url(URI.t() | binary()) :: :ok | :error
defp validate_page_url(page_url) when is_binary(page_url) do
validate_tld = Pleroma.Config.get([Pleroma.Formatter, :validate_tld])
@@ -77,4 +82,20 @@ defmodule Pleroma.Web.RichMedia.Helpers do
fetch_data_for_activity(activity)
:ok
end
+
+ def rich_media_get(url) do
+ headers = [{"user-agent", Pleroma.Application.user_agent() <> "; Bot"}]
+
+ options =
+ if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Hackney do
+ Keyword.merge(@rich_media_options,
+ recv_timeout: 2_000,
+ with_body: true
+ )
+ else
+ @rich_media_options
+ end
+
+ Pleroma.HTTP.get(url, headers, options)
+ end
end
diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex
index c8a767935..ca592833f 100644
--- a/lib/pleroma/web/rich_media/parser.ex
+++ b/lib/pleroma/web/rich_media/parser.ex
@@ -3,11 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.RichMedia.Parser do
- @options [
- pool: :media,
- max_body: 2_000_000
- ]
-
defp parsers do
Pleroma.Config.get([:rich_media, :parsers])
end
@@ -75,21 +70,8 @@ defmodule Pleroma.Web.RichMedia.Parser do
end
defp parse_url(url) do
- opts =
- if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Hackney do
- Keyword.merge(@options,
- recv_timeout: 2_000,
- with_body: true
- )
- else
- @options
- end
-
try do
- rich_media_agent = Pleroma.Application.user_agent() <> "; Bot"
-
- {:ok, %Tesla.Env{body: html}} =
- Pleroma.HTTP.get(url, [{"user-agent", rich_media_agent}], adapter: opts)
+ {:ok, %Tesla.Env{body: html}} = Pleroma.Web.RichMedia.Helpers.rich_media_get(url)
html
|> parse_html()
diff --git a/lib/pleroma/web/rich_media/parsers/oembed_parser.ex b/lib/pleroma/web/rich_media/parsers/oembed_parser.ex
index 6bdeac89c..1fe6729c3 100644
--- a/lib/pleroma/web/rich_media/parsers/oembed_parser.ex
+++ b/lib/pleroma/web/rich_media/parsers/oembed_parser.ex
@@ -22,7 +22,7 @@ defmodule Pleroma.Web.RichMedia.Parsers.OEmbed do
end
defp get_oembed_data(url) do
- with {:ok, %Tesla.Env{body: json}} <- Pleroma.HTTP.get(url, [], adapter: [pool: :media]) do
+ with {:ok, %Tesla.Env{body: json}} <- Pleroma.Web.RichMedia.Helpers.rich_media_get(url) do
Jason.decode(json)
end
end
diff --git a/lib/pleroma/web/templates/layout/app.html.eex b/lib/pleroma/web/templates/layout/app.html.eex
index 5836ec1e0..51603fe0c 100644
--- a/lib/pleroma/web/templates/layout/app.html.eex
+++ b/lib/pleroma/web/templates/layout/app.html.eex
@@ -37,7 +37,7 @@
}
a {
- color: color: #d8a070;
+ color: #d8a070;
text-decoration: none;
}
diff --git a/mix.exs b/mix.exs
index 0e723c15f..63142dee7 100644
--- a/mix.exs
+++ b/mix.exs
@@ -214,7 +214,8 @@ defmodule Pleroma.Mixfile do
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate", "test"],
- docs: ["pleroma.docs", "docs"]
+ docs: ["pleroma.docs", "docs"],
+ analyze: ["credo --strict --only=warnings,todo,fixme,consistency,readability"]
]
end
diff --git a/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs b/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs
new file mode 100644
index 000000000..389935f0d
--- /dev/null
+++ b/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs
@@ -0,0 +1,19 @@
+defmodule Pleroma.Repo.Migrations.RemoveNonlocalExpirations do
+ use Ecto.Migration
+
+ def up do
+ statement = """
+ DELETE FROM
+ activity_expirations A USING activities B
+ WHERE
+ A.activity_id = B.id
+ AND B.local = false;
+ """
+
+ execute(statement)
+ end
+
+ def down do
+ :ok
+ end
+end
diff --git a/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs b/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs
new file mode 100644
index 000000000..83de18096
--- /dev/null
+++ b/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs
@@ -0,0 +1,7 @@
+defmodule Pleroma.Repo.Migrations.AddUniqueIndexToAppClientId do
+ use Ecto.Migration
+
+ def change do
+ create(unique_index(:apps, [:client_id]))
+ end
+end
diff --git a/test/config_test.exs b/test/config_test.exs
index a46ab4302..1556e4237 100644
--- a/test/config_test.exs
+++ b/test/config_test.exs
@@ -28,6 +28,34 @@ defmodule Pleroma.ConfigTest do
assert Pleroma.Config.get([:azerty, :uiop], true) == true
end
+ describe "nil values" do
+ setup do
+ Pleroma.Config.put(:lorem, nil)
+ Pleroma.Config.put(:ipsum, %{dolor: [sit: nil]})
+ Pleroma.Config.put(:dolor, sit: %{amet: nil})
+
+ on_exit(fn -> Enum.each(~w(lorem ipsum dolor)a, &Pleroma.Config.delete/1) end)
+ end
+
+ test "get/1 with an atom for nil value" do
+ assert Pleroma.Config.get(:lorem) == nil
+ end
+
+ test "get/2 with an atom for nil value" do
+ assert Pleroma.Config.get(:lorem, true) == nil
+ end
+
+ test "get/1 with a list of keys for nil value" do
+ assert Pleroma.Config.get([:ipsum, :dolor, :sit]) == nil
+ assert Pleroma.Config.get([:dolor, :sit, :amet]) == nil
+ end
+
+ test "get/2 with a list of keys for nil value" do
+ assert Pleroma.Config.get([:ipsum, :dolor, :sit], true) == nil
+ assert Pleroma.Config.get([:dolor, :sit, :amet], true) == nil
+ end
+ end
+
test "get/1 when value is false" do
Pleroma.Config.put([:instance, :false_test], false)
Pleroma.Config.put([:instance, :nested], [])
@@ -89,5 +117,23 @@ defmodule Pleroma.ConfigTest do
Pleroma.Config.put([:delete_me, :delete_me], hello: "world", world: "Hello")
Pleroma.Config.delete([:delete_me, :delete_me, :world])
assert Pleroma.Config.get([:delete_me, :delete_me]) == [hello: "world"]
+
+ assert Pleroma.Config.delete([:this_key_does_not_exist])
+ assert Pleroma.Config.delete([:non, :existing, :key])
+ end
+
+ test "fetch/1" do
+ Pleroma.Config.put([:lorem], :ipsum)
+ Pleroma.Config.put([:ipsum], dolor: :sit)
+
+ assert Pleroma.Config.fetch([:lorem]) == {:ok, :ipsum}
+ assert Pleroma.Config.fetch(:lorem) == {:ok, :ipsum}
+ assert Pleroma.Config.fetch([:ipsum, :dolor]) == {:ok, :sit}
+ assert Pleroma.Config.fetch([:lorem, :ipsum]) == :error
+ assert Pleroma.Config.fetch([:loremipsum]) == :error
+ assert Pleroma.Config.fetch(:loremipsum) == :error
+
+ Pleroma.Config.delete([:lorem])
+ Pleroma.Config.delete([:ipsum])
end
end
diff --git a/test/report_note_test.exs b/test/report_note_test.exs
new file mode 100644
index 000000000..25c1d6a61
--- /dev/null
+++ b/test/report_note_test.exs
@@ -0,0 +1,16 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.ReportNoteTest do
+ alias Pleroma.ReportNote
+ use Pleroma.DataCase
+ import Pleroma.Factory
+
+ test "create/3" do
+ user = insert(:user)
+ report = insert(:report_activity)
+ assert {:ok, note} = ReportNote.create(user.id, report.id, "naughty boy")
+ assert note.content == "naughty boy"
+ end
+end
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 635d83650..486eda8da 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -297,6 +297,30 @@ defmodule Pleroma.Factory do
}
end
+ def report_activity_factory(attrs \\ %{}) do
+ user = attrs[:user] || insert(:user)
+ activity = attrs[:activity] || insert(:note_activity)
+ state = attrs[:state] || "open"
+
+ data = %{
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
+ "actor" => user.ap_id,
+ "type" => "Flag",
+ "object" => [activity.actor, activity.data["id"]],
+ "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
+ "to" => [],
+ "cc" => [activity.actor],
+ "context" => activity.data["context"],
+ "state" => state
+ }
+
+ %Pleroma.Activity{
+ data: data,
+ actor: data["actor"],
+ recipients: data["to"] ++ data["cc"]
+ }
+ end
+
def oauth_app_factory do
%Pleroma.Web.OAuth.App{
client_name: sequence(:client_name, &"Some client #{&1}"),
diff --git a/test/support/helpers.ex b/test/support/helpers.ex
index 5cbf2e291..ecd4b1e18 100644
--- a/test/support/helpers.ex
+++ b/test/support/helpers.ex
@@ -17,9 +17,19 @@ defmodule Pleroma.Tests.Helpers do
defmacro clear_config(config_path, do: yield) do
quote do
- initial_setting = Config.get(unquote(config_path))
+ initial_setting = Config.fetch(unquote(config_path))
unquote(yield)
- on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
+
+ on_exit(fn ->
+ case initial_setting do
+ :error ->
+ Config.delete(unquote(config_path))
+
+ {:ok, value} ->
+ Config.put(unquote(config_path), value)
+ end
+ end)
+
:ok
end
end
diff --git a/test/tasks/app_test.exs b/test/tasks/app_test.exs
index b8f03566d..71a84ac8e 100644
--- a/test/tasks/app_test.exs
+++ b/test/tasks/app_test.exs
@@ -50,13 +50,13 @@ defmodule Mix.Tasks.Pleroma.AppTest do
defp assert_app(name, redirect, scopes) do
app = Repo.get_by(Pleroma.Web.OAuth.App, client_name: name)
- assert_received {:mix_shell, :info, [message]}
+ assert_receive {:mix_shell, :info, [message]}
assert message == "#{name} successfully created:"
- assert_received {:mix_shell, :info, [message]}
+ assert_receive {:mix_shell, :info, [message]}
assert message == "App client_id: #{app.client_id}"
- assert_received {:mix_shell, :info, [message]}
+ assert_receive {:mix_shell, :info, [message]}
assert message == "App client_secret: #{app.client_secret}"
assert app.scopes == scopes
diff --git a/test/user/welcome_chat_massage_test.exs b/test/user/welcome_chat_massage_test.exs
new file mode 100644
index 000000000..fe26d6e4d
--- /dev/null
+++ b/test/user/welcome_chat_massage_test.exs
@@ -0,0 +1,35 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.User.WelcomeChatMessageTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Config
+ alias Pleroma.User.WelcomeChatMessage
+
+ import Pleroma.Factory
+
+ setup do: clear_config([:welcome])
+
+ describe "post_message/1" do
+ test "send a chat welcome message" do
+ welcome_user = insert(:user, name: "mewmew")
+ user = insert(:user)
+
+ Config.put([:welcome, :chat_message, :enabled], true)
+ Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
+
+ Config.put(
+ [:welcome, :chat_message, :message],
+ "Hello, welcome to Blob/Cat!"
+ )
+
+ {:ok, %Pleroma.Activity{} = activity} = WelcomeChatMessage.post_message(user)
+
+ assert user.ap_id in activity.recipients
+ assert Pleroma.Object.normalize(activity).data["type"] == "ChatMessage"
+ assert Pleroma.Object.normalize(activity).data["content"] == "Hello, welcome to Blob/Cat!"
+ end
+ end
+end
diff --git a/test/user_test.exs b/test/user_test.exs
index 904cea536..b47405895 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -412,8 +412,36 @@ defmodule Pleroma.UserTest do
welcome_user = insert(:user)
Pleroma.Config.put([:welcome, :direct_message, :enabled], true)
Pleroma.Config.put([:welcome, :direct_message, :sender_nickname], welcome_user.nickname)
- Pleroma.Config.put([:welcome, :direct_message, :message], "Hello, this is a cool site")
+ Pleroma.Config.put([:welcome, :direct_message, :message], "Hello, this is a direct message")
+ cng = User.register_changeset(%User{}, @full_user_data)
+ {:ok, registered_user} = User.register(cng)
+ ObanHelpers.perform_all()
+
+ activity = Repo.one(Pleroma.Activity)
+ assert registered_user.ap_id in activity.recipients
+ assert Object.normalize(activity).data["content"] =~ "direct message"
+ assert activity.actor == welcome_user.ap_id
+ end
+
+ test "it sends a welcome chat message if it is set" do
+ welcome_user = insert(:user)
+ Pleroma.Config.put([:welcome, :chat_message, :enabled], true)
+ Pleroma.Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
+ Pleroma.Config.put([:welcome, :chat_message, :message], "Hello, this is a chat message")
+
+ cng = User.register_changeset(%User{}, @full_user_data)
+ {:ok, registered_user} = User.register(cng)
+ ObanHelpers.perform_all()
+
+ activity = Repo.one(Pleroma.Activity)
+ assert registered_user.ap_id in activity.recipients
+ assert Object.normalize(activity).data["content"] =~ "chat message"
+ assert activity.actor == welcome_user.ap_id
+ end
+
+ test "it sends a welcome email message if it is set" do
+ welcome_user = insert(:user)
Pleroma.Config.put([:welcome, :email, :enabled], true)
Pleroma.Config.put([:welcome, :email, :sender], welcome_user.email)
@@ -428,11 +456,6 @@ defmodule Pleroma.UserTest do
{:ok, registered_user} = User.register(cng)
ObanHelpers.perform_all()
- activity = Repo.one(Pleroma.Activity)
- assert registered_user.ap_id in activity.recipients
- assert Object.normalize(activity).data["content"] =~ "cool site"
- assert activity.actor == welcome_user.ap_id
-
assert_email_sent(
from: {instance_name, welcome_user.email},
to: {registered_user.name, registered_user.email},
@@ -490,6 +513,29 @@ defmodule Pleroma.UserTest do
refute changeset.valid?
end
+ test "it blocks blacklisted email domains" do
+ clear_config([User, :email_blacklist], ["trolling.world"])
+
+ # Block with match
+ params = Map.put(@full_user_data, :email, "troll@trolling.world")
+ changeset = User.register_changeset(%User{}, params)
+ refute changeset.valid?
+
+ # Block with subdomain match
+ params = Map.put(@full_user_data, :email, "troll@gnomes.trolling.world")
+ changeset = User.register_changeset(%User{}, params)
+ refute changeset.valid?
+
+ # Pass with different domains that are similar
+ params = Map.put(@full_user_data, :email, "troll@gnomestrolling.world")
+ changeset = User.register_changeset(%User{}, params)
+ assert changeset.valid?
+
+ params = Map.put(@full_user_data, :email, "troll@trolling.world.us")
+ changeset = User.register_changeset(%User{}, params)
+ assert changeset.valid?
+ end
+
test "it sets the password_hash and ap_id" do
changeset = User.register_changeset(%User{}, @full_user_data)
diff --git a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs b/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
index 8babf49e7..f25cf8b12 100644
--- a/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
+++ b/test/web/activity_pub/mrf/activity_expiration_policy_test.exs
@@ -7,11 +7,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
alias Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
@id Pleroma.Web.Endpoint.url() <> "/activities/cofe"
+ @local_actor Pleroma.Web.Endpoint.url() <> "/users/cofe"
test "adds `expires_at` property" do
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
+ "actor" => @local_actor,
"type" => "Create",
"object" => %{"type" => "Note"}
})
@@ -25,6 +27,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
assert {:ok, %{"type" => "Create", "expires_at" => ^expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
+ "actor" => @local_actor,
"type" => "Create",
"expires_at" => expires_at,
"object" => %{"type" => "Note"}
@@ -37,6 +40,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
+ "actor" => @local_actor,
"type" => "Create",
"expires_at" => too_distant_future,
"object" => %{"type" => "Note"}
@@ -49,6 +53,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
+ "actor" => "https://example.com/users/cofe",
"type" => "Create",
"object" => %{"type" => "Note"}
})
@@ -60,6 +65,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
+ "actor" => "https://example.com/users/cofe",
"type" => "Follow"
})
@@ -68,6 +74,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
+ "actor" => "https://example.com/users/cofe",
"type" => "Create",
"object" => %{"type" => "Cofe"}
})
diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs
index b0fb753bd..cf6acc9a2 100644
--- a/test/web/activity_pub/mrf/object_age_policy_test.exs
+++ b/test/web/activity_pub/mrf/object_age_policy_test.exs
@@ -38,6 +38,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
end
describe "with reject action" do
+ test "works with objects with empty to or cc fields" do
+ Config.put([:mrf_object_age, :actions], [:reject])
+
+ data =
+ get_old_message()
+ |> Map.put("cc", nil)
+ |> Map.put("to", nil)
+
+ assert match?({:reject, _}, ObjectAgePolicy.filter(data))
+ end
+
test "it rejects an old post" do
Config.put([:mrf_object_age, :actions], [:reject])
@@ -56,6 +67,21 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
end
describe "with delist action" do
+ test "works with objects with empty to or cc fields" do
+ Config.put([:mrf_object_age, :actions], [:delist])
+
+ data =
+ get_old_message()
+ |> Map.put("cc", nil)
+ |> Map.put("to", nil)
+
+ {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
+
+ {:ok, data} = ObjectAgePolicy.filter(data)
+
+ assert Visibility.get_visibility(%{data: data}) == "unlisted"
+ end
+
test "it delists an old post" do
Config.put([:mrf_object_age, :actions], [:delist])
@@ -80,6 +106,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
end
describe "with strip_followers action" do
+ test "works with objects with empty to or cc fields" do
+ Config.put([:mrf_object_age, :actions], [:strip_followers])
+
+ data =
+ get_old_message()
+ |> Map.put("cc", nil)
+ |> Map.put("to", nil)
+
+ {:ok, user} = User.get_or_fetch_by_ap_id(data["actor"])
+
+ {:ok, data} = ObjectAgePolicy.filter(data)
+
+ refute user.follower_address in data["to"]
+ refute user.follower_address in data["cc"]
+ end
+
test "it strips followers collections from an old post" do
Config.put([:mrf_object_age, :actions], [:strip_followers])
diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs
index e842d8d8d..d7dde62c4 100644
--- a/test/web/activity_pub/mrf/simple_policy_test.exs
+++ b/test/web/activity_pub/mrf/simple_policy_test.exs
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
import Pleroma.Factory
alias Pleroma.Config
alias Pleroma.Web.ActivityPub.MRF.SimplePolicy
+ alias Pleroma.Web.CommonAPI
setup do:
clear_config(:mrf_simple,
@@ -15,6 +16,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
federated_timeline_removal: [],
report_removal: [],
reject: [],
+ followers_only: [],
accept: [],
avatar_removal: [],
banner_removal: [],
@@ -261,6 +263,64 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
end
end
+ describe "when :followers_only" do
+ test "is empty" do
+ Config.put([:mrf_simple, :followers_only], [])
+ {_, ftl_message} = build_ftl_actor_and_message()
+ local_message = build_local_message()
+
+ assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message}
+ assert SimplePolicy.filter(local_message) == {:ok, local_message}
+ end
+
+ test "has a matching host" do
+ actor = insert(:user)
+ following_user = insert(:user)
+ non_following_user = insert(:user)
+
+ {:ok, _, _, _} = CommonAPI.follow(following_user, actor)
+
+ activity = %{
+ "actor" => actor.ap_id,
+ "to" => [
+ "https://www.w3.org/ns/activitystreams#Public",
+ following_user.ap_id,
+ non_following_user.ap_id
+ ],
+ "cc" => [actor.follower_address, "http://foo.bar/qux"]
+ }
+
+ dm_activity = %{
+ "actor" => actor.ap_id,
+ "to" => [
+ following_user.ap_id,
+ non_following_user.ap_id
+ ],
+ "cc" => []
+ }
+
+ actor_domain =
+ activity
+ |> Map.fetch!("actor")
+ |> URI.parse()
+ |> Map.fetch!(:host)
+
+ Config.put([:mrf_simple, :followers_only], [actor_domain])
+
+ assert {:ok, new_activity} = SimplePolicy.filter(activity)
+ assert actor.follower_address in new_activity["cc"]
+ assert following_user.ap_id in new_activity["to"]
+ refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["to"]
+ refute "https://www.w3.org/ns/activitystreams#Public" in new_activity["cc"]
+ refute non_following_user.ap_id in new_activity["to"]
+ refute non_following_user.ap_id in new_activity["cc"]
+
+ assert {:ok, new_dm_activity} = SimplePolicy.filter(dm_activity)
+ assert new_dm_activity["to"] == [following_user.ap_id]
+ assert new_dm_activity["cc"] == []
+ end
+ end
+
describe "when :accept" do
test "is empty" do
Config.put([:mrf_simple, :accept], [])
diff --git a/test/web/activity_pub/transmogrifier/chat_message_test.exs b/test/web/activity_pub/transmogrifier/chat_message_test.exs
index d6736dc3e..31274c067 100644
--- a/test/web/activity_pub/transmogrifier/chat_message_test.exs
+++ b/test/web/activity_pub/transmogrifier/chat_message_test.exs
@@ -124,6 +124,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.ChatMessageTest do
{:ok, %Activity{} = _activity} = Transmogrifier.handle_incoming(data)
end
+ test "it doesn't work for deactivated users" do
+ data =
+ File.read!("test/fixtures/create-chat-message.json")
+ |> Poison.decode!()
+
+ _author =
+ insert(:user,
+ ap_id: data["actor"],
+ local: false,
+ last_refreshed_at: DateTime.utc_now(),
+ deactivated: true
+ )
+
+ _recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
+
+ assert {:error, _} = Transmogrifier.handle_incoming(data)
+ end
+
test "it inserts it and creates a chat" do
data =
File.read!("test/fixtures/create-chat-message.json")
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index 7d33feaf2..828964a36 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -163,6 +163,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
end) =~ "[warn] Couldn't fetch \"https://404.site/whatever\", error: nil"
end
+ test "it does not work for deactivated users" do
+ data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
+
+ insert(:user, ap_id: data["actor"], deactivated: true)
+
+ assert {:error, _} = Transmogrifier.handle_incoming(data)
+ end
+
test "it works for incoming notices" do
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index 313dda21b..4ba6232dc 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -458,6 +458,11 @@ defmodule Pleroma.Web.CommonAPITest do
end
describe "posting" do
+ test "deactivated users can't post" do
+ user = insert(:user, deactivated: true)
+ assert {:error, _} = CommonAPI.post(user, %{status: "ye"})
+ end
+
test "it supports explicit addressing" do
user = insert(:user)
user_two = insert(:user)
diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs
index d390c3ce1..17a1e7d66 100644
--- a/test/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/web/mastodon_api/controllers/account_controller_test.exs
@@ -940,17 +940,32 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert refresh
assert scope == "read write follow"
+ clear_config([User, :email_blacklist], ["example.org"])
+
+ params = %{
+ username: "lain",
+ email: "lain@example.org",
+ password: "PlzDontHackLain",
+ bio: "Test Bio",
+ agreement: true
+ }
+
conn =
build_conn()
|> put_req_header("content-type", "multipart/form-data")
|> put_req_header("authorization", "Bearer " <> token)
- |> post("/api/v1/accounts", %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- bio: "Test Bio",
- agreement: true
- })
+ |> post("/api/v1/accounts", params)
+
+ assert %{"error" => "{\"email\":[\"Invalid email\"]}"} =
+ json_response_and_validate_schema(conn, 400)
+
+ Pleroma.Config.put([User, :email_blacklist], [])
+
+ conn =
+ build_conn()
+ |> put_req_header("content-type", "multipart/form-data")
+ |> put_req_header("authorization", "Bearer " <> token)
+ |> post("/api/v1/accounts", params)
%{
"access_token" => token,
diff --git a/test/web/mastodon_api/mastodon_api_test.exs b/test/web/mastodon_api/mastodon_api_test.exs
index c08be37d4..0c5a38bf6 100644
--- a/test/web/mastodon_api/mastodon_api_test.exs
+++ b/test/web/mastodon_api/mastodon_api_test.exs
@@ -17,8 +17,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
test "returns error when followed user is deactivated" do
follower = insert(:user)
user = insert(:user, local: true, deactivated: true)
- {:error, error} = MastodonAPI.follow(follower, user)
- assert error == :rejected
+ assert {:error, _error} = MastodonAPI.follow(follower, user)
end
test "following for user" do
diff --git a/test/web/oauth/app_test.exs b/test/web/oauth/app_test.exs
index 899af648e..993a490e0 100644
--- a/test/web/oauth/app_test.exs
+++ b/test/web/oauth/app_test.exs
@@ -29,5 +29,16 @@ defmodule Pleroma.Web.OAuth.AppTest do
assert exist_app.id == app.id
assert exist_app.scopes == ["read", "write", "follow", "push"]
end
+
+ test "has unique client_id" do
+ insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop")
+
+ error =
+ catch_error(insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop"))
+
+ assert %Ecto.ConstraintError{} = error
+ assert error.constraint == "apps_client_id_index"
+ assert error.type == :unique
+ end
end
end