Browse Source

Merge tag 'v2.0.5' into emr_stable

emr_stable
a1batross 6 months ago
parent
commit
4323c48102
45 changed files with 419 additions and 346 deletions
  1. +40
    -0
      CHANGELOG.md
  2. +1
    -0
      config/description.exs
  3. +1
    -2
      installation/pleroma-apache.conf
  4. +1
    -1
      lib/pleroma/healthcheck.ex
  5. +9
    -1
      lib/pleroma/user.ex
  6. +1
    -3
      lib/pleroma/web/activity_pub/activity_pub.ex
  7. +7
    -4
      lib/pleroma/web/activity_pub/activity_pub_controller.ex
  8. +5
    -1
      lib/pleroma/web/activity_pub/transmogrifier.ex
  9. +6
    -2
      lib/pleroma/web/activity_pub/utils.ex
  10. +14
    -55
      lib/pleroma/web/mastodon_api/websocket_handler.ex
  11. +4
    -15
      lib/pleroma/web/streamer/state.ex
  12. +65
    -0
      lib/pleroma/web/streamer/streamer.ex
  13. +4
    -2
      lib/pleroma/web/web_finger/web_finger.ex
  14. +10
    -3
      mix.exs
  15. +1
    -1
      priv/repo/migrations/20200428221338_insert_skeletons_for_deleted_users.exs
  16. +1
    -1
      priv/static/index.html
  17. BIN
     
  18. BIN
     
  19. BIN
     
  20. +2
    -0
      priv/static/static/font/fontello.1589314090288.svg
  21. BIN
     
  22. BIN
     
  23. BIN
     
  24. +8
    -6
      priv/static/static/fontello.1589314090288.css
  25. +6
    -0
      priv/static/static/fontello.json
  26. +2
    -2
      priv/static/static/js/2.f9a5c4aba770b3f9f9e0.js
  27. +1
    -1
      priv/static/static/js/2.f9a5c4aba770b3f9f9e0.js.map
  28. +0
    -2
      priv/static/static/js/app.57951e6e5e198d1a1266.js
  29. +0
    -1
      priv/static/static/js/app.57951e6e5e198d1a1266.js.map
  30. +2
    -0
      priv/static/static/js/app.82334f8362acc4bbcb6f.js
  31. +1
    -0
      priv/static/static/js/app.82334f8362acc4bbcb6f.js.map
  32. +7
    -7
      priv/static/static/js/vendors~app.a516afd698489b59a809.js
  33. +1
    -0
      priv/static/static/js/vendors~app.a516afd698489b59a809.js.map
  34. +0
    -1
      priv/static/static/js/vendors~app.c67e1a363ece7f1f7152.js.map
  35. +0
    -176
      priv/static/static/static-fe.css
  36. +1
    -1
      priv/static/sw-pleroma.js
  37. +6
    -6
      test/integration/mastodon_websocket_test.exs
  38. +6
    -5
      test/notification_test.exs
  39. +7
    -7
      test/support/http_request_mock.ex
  40. +3
    -0
      test/user_test.exs
  41. +72
    -15
      test/web/activity_pub/activity_pub_controller_test.exs
  42. +33
    -4
      test/web/activity_pub/activity_pub_test.exs
  43. +6
    -0
      test/web/activity_pub/transmogrifier_test.exs
  44. +0
    -2
      test/web/mastodon_api/controllers/suggestion_controller_test.exs
  45. +85
    -19
      test/web/streamer/streamer_test.exs

+ 40
- 0
CHANGELOG.md View File

@@ -3,6 +3,46 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [2.0.5] - 2020-05-13

### Security
- Fix possible private status leaks in Mastodon Streaming API

### Fixed
- Crashes when trying to block a user if block federation is disabled
- Not being able to start the instance without `erlang-eldap` installed
- Users with bios over the limit getting rejected
- Follower counters not being updated on incoming follow accepts

### Upgrade notes

1. Restart Pleroma

## [2.0.4] - 2020-05-10

### Security
- AP C2S: Fix a potential DoS by creating nonsensical objects that break timelines

### Fixed
- Peertube user lookups not working
- `InsertSkeletonsForDeletedUsers` migration failing on some instances
- Healthcheck reporting the number of memory currently used, rather than allocated in total
- LDAP not being usable in OTP releases
- Default apache configuration having tls chain issues

### Upgrade notes

#### Apache only

1. Remove the following line from your config:
```
SSLCertificateFile /etc/letsencrypt/live/${servername}/cert.pem
```

#### Everyone

1. Restart Pleroma

## [2.0.3] - 2020-05-02

### Security


+ 1
- 0
config/description.exs View File

@@ -2260,6 +2260,7 @@ config :pleroma, :config_description, [
children: [
%{
key: :active,
label: "Enabled",
type: :boolean,
description: "Globally enable or disable digest emails"
},


+ 1
- 2
installation/pleroma-apache.conf View File

@@ -32,9 +32,8 @@ CustomLog ${APACHE_LOG_DIR}/access.log combined

<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/${servername}/cert.pem
SSLCertificateFile /etc/letsencrypt/live/${servername}/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/${servername}/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/${servername}/fullchain.pem

# Mozilla modern configuration, tweak to your needs
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1


+ 1
- 1
lib/pleroma/healthcheck.ex View File

@@ -29,7 +29,7 @@ defmodule Pleroma.Healthcheck do
@spec system_info() :: t()
def system_info do
%Healthcheck{
memory_used: Float.round(:erlang.memory(:total) / 1024 / 1024, 2)
memory_used: Float.round(:recon_alloc.memory(:allocated) / 1024 / 1024, 2)
}
|> assign_db_info()
|> assign_job_queue_stats()


+ 9
- 1
lib/pleroma/user.ex View File

@@ -501,7 +501,15 @@ defmodule Pleroma.User do

params = Map.put(params, :last_refreshed_at, NaiveDateTime.utc_now())

params = if remote?, do: truncate_fields_param(params), else: params
params =
if remote? do
params
|> truncate_fields_param()
|> truncate_if_exists(:name, name_limit)
|> truncate_if_exists(:bio, bio_limit)
else
params
end

struct
|> cast(


+ 1
- 3
lib/pleroma/web/activity_pub/activity_pub.ex View File

@@ -604,7 +604,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end

defp do_block(blocker, blocked, activity_id, local) do
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])

if unfollow_blocked do
@@ -612,8 +611,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
if follow_activity, do: unfollow(blocker, blocked, nil, local)
end

with true <- outgoing_blocks,
block_data <- make_block_data(blocker, blocked, activity_id),
with block_data <- make_block_data(blocker, blocked, activity_id),
{:ok, activity} <- insert(block_data, local),
:ok <- maybe_federate(activity) do
{:ok, activity}


+ 7
- 4
lib/pleroma/web/activity_pub/activity_pub_controller.ex View File

@@ -370,7 +370,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|> json(err)
end

def handle_user_activity(user, %{"type" => "Create"} = params) do
defp handle_user_activity(
%User{} = user,
%{"type" => "Create", "object" => %{"type" => "Note"}} = params
) do
object =
params["object"]
|> Map.merge(Map.take(params, ["to", "cc"]))
@@ -386,7 +389,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
})
end

def handle_user_activity(user, %{"type" => "Delete"} = params) do
defp handle_user_activity(user, %{"type" => "Delete"} = params) do
with %Object{} = object <- Object.normalize(params["object"]),
true <- user.is_moderator || user.ap_id == object.data["actor"],
{:ok, delete} <- ActivityPub.delete(object) do
@@ -396,7 +399,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
end
end

def handle_user_activity(user, %{"type" => "Like"} = params) do
defp handle_user_activity(user, %{"type" => "Like"} = params) do
with %Object{} = object <- Object.normalize(params["object"]),
{:ok, activity, _object} <- ActivityPub.like(user, object) do
{:ok, activity}
@@ -405,7 +408,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
end
end

def handle_user_activity(_, _) do
defp handle_user_activity(_, _) do
{:error, dgettext("errors", "Unhandled activity type")}
end



+ 5
- 1
lib/pleroma/web/activity_pub/transmogrifier.ex View File

@@ -544,6 +544,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do
User.update_follower_count(followed)
User.update_following_count(follower)

ActivityPub.accept(%{
to: follow_activity.data["to"],
type: "Accept",
@@ -553,7 +556,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
activity_id: id
})
else
_e -> :error
_e ->
:error
end
end



+ 6
- 2
lib/pleroma/web/activity_pub/utils.ex View File

@@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
alias Ecto.Changeset
alias Ecto.UUID
alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
@@ -169,8 +170,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
Enqueues an activity for federation if it's local
"""
@spec maybe_federate(any()) :: :ok
def maybe_federate(%Activity{local: true} = activity) do
if Pleroma.Config.get!([:instance, :federating]) do
def maybe_federate(%Activity{local: true, data: %{"type" => type}} = activity) do
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])

with true <- Config.get!([:instance, :federating]),
true <- type != "Block" || outgoing_blocks do
Pleroma.Web.Federator.publish(activity)
end



+ 14
- 55
lib/pleroma/web/mastodon_api/websocket_handler.ex View File

@@ -12,29 +12,15 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do

@behaviour :cowboy_websocket

@streams [
"public",
"public:local",
"public:media",
"public:local:media",
"user",
"user:notification",
"direct",
"list",
"hashtag"
]
@anonymous_streams ["public", "public:local", "hashtag"]

# Handled by periodic keepalive in Pleroma.Web.Streamer.Ping.
@timeout :infinity

def init(%{qs: qs} = req, state) do
with params <- :cow_qs.parse_qs(qs),
with params <- Enum.into(:cow_qs.parse_qs(qs), %{}),
sec_websocket <- :cowboy_req.header("sec-websocket-protocol", req, nil),
access_token <- List.keyfind(params, "access_token", 0),
{_, stream} <- List.keyfind(params, "stream", 0),
{:ok, user} <- allow_request(stream, [access_token, sec_websocket]),
topic when is_binary(topic) <- expand_topic(stream, params) do
access_token <- Map.get(params, "access_token"),
{:ok, user} <- authenticate_request(access_token, sec_websocket),
{:ok, topic} <- Streamer.get_topic(Map.get(params, "stream"), user, params) do
req =
if sec_websocket do
:cowboy_req.set_resp_header("sec-websocket-protocol", sec_websocket, req)
@@ -44,14 +30,14 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do

{:cowboy_websocket, req, %{user: user, topic: topic}, %{idle_timeout: @timeout}}
else
{:error, code} ->
Logger.debug("#{__MODULE__} denied connection: #{inspect(code)} - #{inspect(req)}")
{:ok, req} = :cowboy_req.reply(code, req)
{:error, :bad_topic} ->
Logger.debug("#{__MODULE__} bad topic #{inspect(req)}")
{:ok, req} = :cowboy_req.reply(404, req)
{:ok, req, state}

error ->
Logger.debug("#{__MODULE__} denied connection: #{inspect(error)} - #{inspect(req)}")
{:ok, req} = :cowboy_req.reply(400, req)
{:error, :unauthorized} ->
Logger.debug("#{__MODULE__} authentication error: #{inspect(req)}")
{:ok, req} = :cowboy_req.reply(401, req)
{:ok, req, state}
end
end
@@ -93,50 +79,23 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
end

# Public streams without authentication.
defp allow_request(stream, [nil, nil]) when stream in @anonymous_streams do
defp authenticate_request(nil, nil) do
{:ok, nil}
end

# Authenticated streams.
defp allow_request(stream, [access_token, sec_websocket]) when stream in @streams do
token =
with {"access_token", token} <- access_token do
token
else
_ -> sec_websocket
end
defp authenticate_request(access_token, sec_websocket) do
token = access_token || sec_websocket

with true <- is_bitstring(token),
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
user = %User{} <- User.get_cached_by_id(user_id) do
{:ok, user}
else
_ -> {:error, 403}
end
end

# Not authenticated.
defp allow_request(stream, _) when stream in @streams, do: {:error, 403}

# No matching stream.
defp allow_request(_, _), do: {:error, 404}

defp expand_topic("hashtag", params) do
case List.keyfind(params, "tag", 0) do
{_, tag} -> "hashtag:#{tag}"
_ -> nil
_ -> {:error, :unauthorized}
end
end

defp expand_topic("list", params) do
case List.keyfind(params, "list", 0) do
{_, list} -> "list:#{list}"
_ -> nil
end
end

defp expand_topic(topic, _), do: topic

defp streamer_socket(state) do
%{transport_pid: self(), assigns: state}
end


+ 4
- 15
lib/pleroma/web/streamer/state.ex View File

@@ -36,30 +36,28 @@ defmodule Pleroma.Web.Streamer.State do
end

def handle_call({:add, topic, socket}, _from, %{sockets: sockets} = state) do
internal_topic = internal_topic(topic, socket)
stream_socket = StreamerSocket.from_socket(socket)

sockets_for_topic =
sockets
|> Map.get(internal_topic, [])
|> Map.get(topic, [])
|> List.insert_at(0, stream_socket)
|> Enum.uniq()

state = put_in(state, [:sockets, internal_topic], sockets_for_topic)
state = put_in(state, [:sockets, topic], sockets_for_topic)
Logger.debug("Got new conn for #{topic}")
{:reply, state, state}
end

def handle_call({:remove, topic, socket}, _from, %{sockets: sockets} = state) do
internal_topic = internal_topic(topic, socket)
stream_socket = StreamerSocket.from_socket(socket)

sockets_for_topic =
sockets
|> Map.get(internal_topic, [])
|> Map.get(topic, [])
|> List.delete(stream_socket)

state = Kernel.put_in(state, [:sockets, internal_topic], sockets_for_topic)
state = Kernel.put_in(state, [:sockets, topic], sockets_for_topic)
{:reply, state, state}
end

@@ -70,13 +68,4 @@ defmodule Pleroma.Web.Streamer.State do
defp do_remove_socket(_env, topic, socket) do
GenServer.call(__MODULE__, {:remove, topic, socket})
end

defp internal_topic(topic, socket)
when topic in ~w[user user:notification direct] do
"#{topic}:#{socket.assigns[:user].id}"
end

defp internal_topic(topic, _) do
topic
end
end

+ 65
- 0
lib/pleroma/web/streamer/streamer.ex View File

@@ -3,12 +3,77 @@
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Web.Streamer do
alias Pleroma.User
alias Pleroma.Web.Streamer.State
alias Pleroma.Web.Streamer.Worker

@timeout 60_000
@mix_env Mix.env()

@public_streams ["public", "public:local", "public:media", "public:local:media"]
@user_streams ["user", "user:notification", "direct"]

@doc "Expands and authorizes a stream, and registers the process for streaming."
@spec get_topic_and_add_socket(stream :: String.t(), State.t(), Map.t() | nil) ::
{:ok, topic :: String.t()} | {:error, :bad_topic} | {:error, :unauthorized}
def get_topic_and_add_socket(stream, socket, params \\ %{}) do
user =
case socket do
%{assigns: %{user: user}} -> user
_ -> nil
end

case get_topic(stream, user, params) do
{:ok, topic} ->
add_socket(topic, socket)
{:ok, topic}

error ->
error
end
end

@doc "Expand and authorizes a stream"
@spec get_topic(stream :: String.t(), User.t() | nil, Map.t()) ::
{:ok, topic :: String.t()} | {:error, :bad_topic}
def get_topic(stream, user, params \\ %{})

# Allow all public steams.
def get_topic(stream, _, _) when stream in @public_streams do
{:ok, stream}
end

# Allow all hashtags streams.
def get_topic("hashtag", _, %{"tag" => tag}) do
{:ok, "hashtag:" <> tag}
end

# Expand user streams.
def get_topic(stream, %User{} = user, _) when stream in @user_streams do
{:ok, stream <> ":" <> to_string(user.id)}
end

def get_topic(stream, _, _) when stream in @user_streams do
{:error, :unauthorized}
end

# List streams.
def get_topic("list", %User{} = user, %{"list" => id}) do
if Pleroma.List.get(id, user) do
{:ok, "list:" <> to_string(id)}
else
{:error, :bad_topic}
end
end

def get_topic("list", _, _) do
{:error, :unauthorized}
end

def get_topic(_, _, _) do
{:error, :bad_topic}
end

def add_socket(topic, socket) do
State.add_socket(topic, socket)
end


+ 4
- 2
lib/pleroma/web/web_finger/web_finger.ex View File

@@ -193,13 +193,15 @@ defmodule Pleroma.Web.WebFinger do
URI.parse(account).host
end

encoded_account = URI.encode("acct:#{account}")

address =
case find_lrdd_template(domain) do
{:ok, template} ->
String.replace(template, "{uri}", URI.encode(account))
String.replace(template, "{uri}", encoded_account)

_ ->
"https://#{domain}/.well-known/webfinger?resource=acct:#{account}"
"https://#{domain}/.well-known/webfinger?resource=#{encoded_account}"
end

with response <-


+ 10
- 3
mix.exs View File

@@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
def project do
[
app: :pleroma,
version: version("2.0.3"),
version: version("2.0.5"),
elixir: "~> 1.8",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
@@ -36,7 +36,7 @@ defmodule Pleroma.Mixfile do
releases: [
pleroma: [
include_executables_for: [:unix],
applications: [ex_syslogger: :load, syslog: :load],
applications: [ex_syslogger: :load, syslog: :load, eldap: :transient],
steps: [:assemble, &copy_files/1, &copy_nginx_config/1]
]
]
@@ -63,7 +63,14 @@ defmodule Pleroma.Mixfile do
def application do
[
mod: {Pleroma.Application, []},
extra_applications: [:logger, :runtime_tools, :comeonin, :quack, :fast_sanitize, :ssl],
extra_applications: [
:logger,
:runtime_tools,
:comeonin,
:quack,
:fast_sanitize,
:ssl
],
included_applications: [:ex_syslogger]
]
end


+ 1
- 1
priv/repo/migrations/20200428221338_insert_skeletons_for_deleted_users.exs View File

@@ -30,7 +30,7 @@ defmodule Pleroma.Repo.Migrations.InsertSkeletonsForDeletedUsers do
Repo,
"select distinct unnest(nonexistent_locals.recipients) from activities, lateral (select array_agg(recipient) as recipients from unnest(activities.recipients) as recipient where recipient similar to '#{
instance_uri
}/users/[A-Za-z0-9]*' and not(recipient in (select ap_id from users where local = true))) nonexistent_locals;",
}/users/[A-Za-z0-9]*' and not(recipient in (select ap_id from users))) nonexistent_locals;",
[],
timeout: :infinity
)


+ 1
- 1
priv/static/index.html View File

@@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.1055039ce3f2fe4dd110.css rel=stylesheet><link href=/static/fontello.1588431888583.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.c67e1a363ece7f1f7152.js></script><script type=text/javascript src=/static/js/app.57951e6e5e198d1a1266.js></script></body></html>
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.1055039ce3f2fe4dd110.css rel=stylesheet><link href=/static/fontello.1589314090288.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.a516afd698489b59a809.js></script><script type=text/javascript src=/static/js/app.82334f8362acc4bbcb6f.js></script></body></html>

BIN
View File


BIN
View File


BIN
View File


priv/static/static/font/fontello.1588431888583.svg → priv/static/static/font/fontello.1589314090288.svg View File

@@ -114,6 +114,8 @@

<glyph glyph-name="thumbs-up-alt" unicode="&#xf164;" d="M143 107q0 15-11 25t-25 11q-15 0-25-11t-11-25q0-15 11-25t25-11q15 0 25 11t11 25z m89 286v-357q0-15-10-25t-26-11h-160q-15 0-25 11t-11 25v357q0 14 11 25t25 10h160q15 0 26-10t10-25z m661 0q0-48-31-83 9-25 9-43 1-42-24-76 9-31 0-66-9-31-31-52 5-62-27-101-36-43-110-44h-72q-37 0-80 9t-68 16-67 22q-69 24-88 25-15 0-25 11t-11 25v357q0 14 10 25t24 11q13 1 42 33t57 67q38 49 56 67 10 10 17 27t10 27 8 34q4 22 7 34t11 29 19 28q10 11 25 11 25 0 46-6t33-15 22-22 14-25 7-28 2-25 1-22q0-21-6-43t-10-33-16-31q-1-4-5-10t-6-13-5-13h155q43 0 75-32t32-75z" horiz-adv-x="928.6" />

<glyph glyph-name="share" unicode="&#xf1e0;" d="M679 286q74 0 126-53t52-126-52-126-126-53-127 53-52 126q0 7 1 19l-201 100q-51-48-121-48-75 0-127 53t-52 126 52 126 127 53q70 0 121-48l201 100q-1 12-1 19 0 74 52 126t127 53 126-53 52-126-52-126-126-53q-71 0-122 48l-201-100q1-12 1-19t-1-19l201-100q51 48 122 48z" horiz-adv-x="857.1" />

<glyph glyph-name="binoculars" unicode="&#xf1e5;" d="M393 678v-428q0-15-11-25t-25-11v-321q0-15-10-25t-26-11h-285q-15 0-25 11t-11 25v285l139 488q4 12 17 12h237z m178 0v-392h-142v392h142z m429-500v-285q0-15-11-25t-25-11h-285q-15 0-25 11t-11 25v321q-15 0-25 11t-11 25v428h237q13 0 17-12z m-589 661v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z m375 0v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z" horiz-adv-x="1000" />

<glyph glyph-name="user-plus" unicode="&#xf234;" d="M393 357q-89 0-152 63t-62 151 62 152 152 63 151-63 63-152-63-151-151-63z m536-71h196q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-196v-197q0-7-6-12t-12-6h-107q-8 0-13 6t-5 12v197h-197q-7 0-12 5t-6 13v107q0 7 6 12t12 6h197v196q0 7 5 13t13 5h107q7 0 12-5t6-13v-196z m-411-125q0-29 21-51t50-21h143v-133q-38-28-95-28h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q11 0 22-10 44-34 86-51t92-17 92 17 86 51q11 10 22 10 73 0 121-54h-125q-29 0-50-21t-21-50v-107z" horiz-adv-x="1142.9" />

BIN
View File


BIN
View File


BIN
View File


priv/static/static/fontello.1588431888583.css → priv/static/static/fontello.1589314090288.css View File

@@ -1,11 +1,11 @@
@font-face {
font-family: "Icons";
src: url("./font/fontello.1588431888583.eot");
src: url("./font/fontello.1588431888583.eot") format("embedded-opentype"),
url("./font/fontello.1588431888583.woff2") format("woff2"),
url("./font/fontello.1588431888583.woff") format("woff"),
url("./font/fontello.1588431888583.ttf") format("truetype"),
url("./font/fontello.1588431888583.svg") format("svg");
src: url("./font/fontello.1589314090288.eot");
src: url("./font/fontello.1589314090288.eot") format("embedded-opentype"),
url("./font/fontello.1589314090288.woff2") format("woff2"),
url("./font/fontello.1589314090288.woff") format("woff"),
url("./font/fontello.1589314090288.ttf") format("truetype"),
url("./font/fontello.1589314090288.svg") format("svg");
font-weight: normal;
font-style: normal;
}
@@ -137,6 +137,8 @@

.icon-link::before { content: "\e823"; }

.icon-share::before { content: "\f1e0"; }

.icon-user::before { content: "\e824"; }

.icon-ok::before { content: "\e827"; }

+ 6
- 0
priv/static/static/fontello.json View File

@@ -346,6 +346,12 @@
"code": 59427,
"src": "fontawesome"
},
{
"uid": "4aad6bb50b02c18508aae9cbe14e784e",
"css": "share",
"code": 61920,
"src": "fontawesome"
},
{
"uid": "8b80d36d4ef43889db10bc1f0dc9a862",
"css": "user",


priv/static/static/js/2.93c984e8c993f92c77a1.js → priv/static/static/js/2.f9a5c4aba770b3f9f9e0.js View File

@@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{580:function(t,e,i){var c=i(581);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(4).default)("cc6cdea4",c,!0,{})},581:function(t,e,i){(t.exports=i(3)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},582:function(t,e,i){"use strict";i.r(e);var c=i(90),a={components:{TabSwitcher:i(52).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,a=this.$store;fetch(t).then(function(t){t.blob().then(function(t){var n=new File([t],e,{mimetype:"image/png"}),s=new FormData;s.append("file",n),c.a.uploadMedia({store:a,formData:s}).then(function(t){i.$emit("uploaded",t),i.clear()},function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")})})})}}},n=i(0);var s=function(t){i(580)},r=Object(n.a)(a,function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])}),0)}),0)],1)},[],!1,s,null,null);e.default=r.exports}}]);
//# sourceMappingURL=2.93c984e8c993f92c77a1.js.map
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{582:function(t,e,i){var c=i(583);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(3).default)("cc6cdea4",c,!0,{})},583:function(t,e,i){(t.exports=i(2)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},584:function(t,e,i){"use strict";i.r(e);var c=i(90),a={components:{TabSwitcher:i(52).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,a=this.$store;fetch(t).then(function(t){t.blob().then(function(t){var n=new File([t],e,{mimetype:"image/png"}),s=new FormData;s.append("file",n),c.a.uploadMedia({store:a,formData:s}).then(function(t){i.$emit("uploaded",t),i.clear()},function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")})})})}}},n=i(0);var s=function(t){i(582)},r=Object(n.a)(a,function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])}),0)}),0)],1)},[],!1,s,null,null);e.default=r.exports}}]);
//# sourceMappingURL=2.f9a5c4aba770b3f9f9e0.js.map

priv/static/static/js/2.f9a5c4aba770b3f9f9e0.js.map
File diff suppressed because it is too large
View File


+ 0
- 2
priv/static/static/js/app.57951e6e5e198d1a1266.js
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/static/js/app.57951e6e5e198d1a1266.js.map
File diff suppressed because it is too large
View File


+ 2
- 0
priv/static/static/js/app.82334f8362acc4bbcb6f.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/static/js/app.82334f8362acc4bbcb6f.js.map
File diff suppressed because it is too large
View File


priv/static/static/js/vendors~app.a516afd698489b59a809.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/static/js/vendors~app.a516afd698489b59a809.js.map
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/static/js/vendors~app.c67e1a363ece7f1f7152.js.map
File diff suppressed because it is too large
View File


+ 0
- 176
priv/static/static/static-fe.css View File

@@ -1,176 +0,0 @@
body {
background-color: #282c37;
font-family: sans-serif;
color: white;
}

main {
margin: 50px auto;
max-width: 960px;
padding: 40px;
background-color: #313543;
border-radius: 4px;
}

header {
margin: 50px auto;
max-width: 960px;
padding: 40px;
background-color: #313543;
border-radius: 4px;
}

.activity {
border-radius: 4px;
padding: 1em;
padding-bottom: 2em;
margin-bottom: 1em;
}

.avatar {
cursor: pointer;
}

.avatar img {
float: left;
border-radius: 4px;
margin-right: 4px;
}

.activity-content img, video, audio {
padding: 1em;
max-width: 800px;
max-height: 800px;
}

#selected {
background-color: #1b2735;
}

.counts dt, .counts dd {
float: left;
margin-left: 1em;
}

a {
color: white;
}

.h-card {
min-height: 48px;
margin-bottom: 8px;
}

header a, .h-card a {
text-decoration: none;
}

header a:hover, .h-card a:hover {
text-decoration: underline;
}

.display-name {
padding-top: 4px;
display: block;
text-overflow: ellipsis;
overflow: hidden;
color: white;
}

/* keep emoji from being hilariously huge */
.display-name img {
max-height: 1em;
}

.display-name .nickname {
padding-top: 4px;
display: block;
}

.nickname:hover {
text-decoration: none;
}

.pull-right {
float: right;
}

.collapse {
margin: 0;
width: auto;
}

h1 {
margin: 0;
}

h2 {
color: #9baec8;
font-weight: normal;
font-size: 20px;
margin-bottom: 40px;
}

form {
width: 100%;
}

input {
box-sizing: border-box;
width: 100%;
padding: 10px;
margin-top: 20px;
background-color: rgba(0,0,0,.1);
color: white;
border: 0;
border-bottom: 2px solid #9baec8;
font-size: 14px;
}

input:focus {
border-bottom: 2px solid #4b8ed8;
}

input[type="checkbox"] {
width: auto;
}

button {
box-sizing: border-box;
width: 100%;
color: white;
background-color: #419bdd;
border-radius: 4px;
border: none;
padding: 10px;
margin-top: 30px;
text-transform: uppercase;
font-weight: 500;
font-size: 16px;
}

.alert-danger {
box-sizing: border-box;
width: 100%;
color: #D8000C;
background-color: #FFD2D2;
border-radius: 4px;
border: none;
padding: 10px;
margin-top: 20px;
font-weight: 500;
font-size: 16px;
}

.alert-info {
box-sizing: border-box;
width: 100%;
color: #00529B;
background-color: #BDE5F8;
border-radius: 4px;
border: none;
padding: 10px;
margin-top: 20px;
font-weight: 500;
font-size: 16px;
}

+ 1
- 1
priv/static/sw-pleroma.js View File

@@ -1,4 +1,4 @@
var serviceWorkerOption = {"assets":["/static/fontello.1588431888583.css","/static/font/fontello.1588431888583.eot","/static/font/fontello.1588431888583.svg","/static/font/fontello.1588431888583.ttf","/static/font/fontello.1588431888583.woff","/static/font/fontello.1588431888583.woff2","/static/img/nsfw.74818f9.png","/static/css/app.1055039ce3f2fe4dd110.css","/static/js/app.57951e6e5e198d1a1266.js","/static/css/vendors~app.b2603a50868c68a1c192.css","/static/js/vendors~app.c67e1a363ece7f1f7152.js","/static/js/2.93c984e8c993f92c77a1.js"]};
var serviceWorkerOption = {"assets":["/static/fontello.1589314090288.css","/static/font/fontello.1589314090288.eot","/static/font/fontello.1589314090288.svg","/static/font/fontello.1589314090288.ttf","/static/font/fontello.1589314090288.woff","/static/font/fontello.1589314090288.woff2","/static/img/nsfw.74818f9.png","/static/css/app.1055039ce3f2fe4dd110.css","/static/js/app.82334f8362acc4bbcb6f.js","/static/css/vendors~app.b2603a50868c68a1c192.css","/static/js/vendors~app.a516afd698489b59a809.js","/static/js/2.f9a5c4aba770b3f9f9e0.js"]};
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t(t.s=1)}([function(e,n){
/*!


+ 6
- 6
test/integration/mastodon_websocket_test.exs View File

@@ -35,7 +35,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do

test "refuses invalid requests" do
capture_log(fn ->
assert {:error, {400, _}} = start_socket()
assert {:error, {404, _}} = start_socket()
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
Process.sleep(30)
end)
@@ -43,8 +43,8 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do

test "requires authentication and a valid token for protected streams" do
capture_log(fn ->
assert {:error, {403, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
assert {:error, {403, _}} = start_socket("?stream=user")
assert {:error, {401, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
assert {:error, {401, _}} = start_socket("?stream=user")
Process.sleep(30)
end)
end
@@ -103,7 +103,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")

assert capture_log(fn ->
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user")
assert {:error, {401, _}} = start_socket("?stream=user")
Process.sleep(30)
end) =~ ":badarg"
end
@@ -112,7 +112,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")

assert capture_log(fn ->
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user:notification")
assert {:error, {401, _}} = start_socket("?stream=user:notification")
Process.sleep(30)
end) =~ ":badarg"
end
@@ -121,7 +121,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])

assert capture_log(fn ->
assert {:error, {403, "Forbidden"}} =
assert {:error, {401, _}} =
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])

Process.sleep(30)


+ 6
- 5
test/notification_test.exs View File

@@ -164,12 +164,13 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
task = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
task_user_notification = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
Streamer.add_socket("user", %{transport_pid: task.pid, assigns: %{user: user}})

Streamer.add_socket(
"user:notification",
%{transport_pid: task_user_notification.pid, assigns: %{user: user}}
)
Streamer.get_topic_and_add_socket("user", %{transport_pid: task.pid, assigns: %{user: user}})

Streamer.get_topic_and_add_socket("user:notification", %{
transport_pid: task_user_notification.pid,
assigns: %{user: user}
})

activity = insert(:note_activity)



+ 7
- 7
test/support/http_request_mock.ex View File

@@ -211,7 +211,7 @@ defmodule HttpRequestMock do
end

def get(
"https://squeet.me/xrd/?uri=lain@squeet.me",
"https://squeet.me/xrd/?uri=acct:lain@squeet.me",
_,
_,
Accept: "application/xrd+xml,application/jrd+json"
@@ -850,7 +850,7 @@ defmodule HttpRequestMock do
end

def get(
"https://social.heldscal.la/.well-known/webfinger?resource=shp@social.heldscal.la",
"https://social.heldscal.la/.well-known/webfinger?resource=acct:shp@social.heldscal.la",
_,
_,
Accept: "application/xrd+xml,application/jrd+json"
@@ -863,7 +863,7 @@ defmodule HttpRequestMock do
end

def get(
"https://social.heldscal.la/.well-known/webfinger?resource=invalid_content@social.heldscal.la",
"https://social.heldscal.la/.well-known/webfinger?resource=acct:invalid_content@social.heldscal.la",
_,
_,
Accept: "application/xrd+xml,application/jrd+json"
@@ -880,7 +880,7 @@ defmodule HttpRequestMock do
end

def get(
"http://framatube.org/main/xrd?uri=framasoft@framatube.org",
"http://framatube.org/main/xrd?uri=acct:framasoft@framatube.org",
_,
_,
Accept: "application/xrd+xml,application/jrd+json"
@@ -939,7 +939,7 @@ defmodule HttpRequestMock do
end

def get(
"https://gerzilla.de/xrd/?uri=kaniini@gerzilla.de",
"https://gerzilla.de/xrd/?uri=acct:kaniini@gerzilla.de",
_,
_,
Accept: "application/xrd+xml,application/jrd+json"
@@ -1135,7 +1135,7 @@ defmodule HttpRequestMock do
end

def get(
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=lain@zetsubou.xn--q9jyb4c",
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=acct:lain@zetsubou.xn--q9jyb4c",
_,
_,
Accept: "application/xrd+xml,application/jrd+json"
@@ -1148,7 +1148,7 @@ defmodule HttpRequestMock do
end

def get(
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=https://zetsubou.xn--q9jyb4c/users/lain",
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=acct:https://zetsubou.xn--q9jyb4c/users/lain",
_,
_,
Accept: "application/xrd+xml,application/jrd+json"


+ 3
- 0
test/user_test.exs View File

@@ -570,7 +570,10 @@ defmodule Pleroma.UserTest do
assert fetched_user == "not found nonexistant"
end

clear_config([:instance, :user_bio_length])

test "updates an existing user, if stale" do
Pleroma.Config.put([:instance, :user_bio_length], 1)
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)

orig_user =


+ 72
- 15
test/web/activity_pub/activity_pub_controller_test.exs View File

@@ -310,7 +310,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end

describe "/inbox" do
clear_config([:instance, :user_bio_length])

test "it inserts an incoming activity into the database", %{conn: conn} do
Pleroma.Config.put([:instance, :user_bio_length], 1)

data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()

conn =
@@ -652,9 +656,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do

assert response(conn, 200) =~ announce_activity.data["object"]
end
end

describe "POST /users/:nickname/outbox (C2S)" do
setup do
[
activity: %{
"@context" => "https://www.w3.org/ns/activitystreams",
"type" => "Create",
"object" => %{"type" => "Note", "content" => "AP C2S test"},
"to" => "https://www.w3.org/ns/activitystreams#Public",
"cc" => []
}
]
end

test "it rejects posts from other users", %{conn: conn} do
data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
test "it rejects posts from other users / unauthenticated users", %{
conn: conn,
activity: activity
} do
user = insert(:user)
otheruser = insert(:user)

@@ -662,39 +682,76 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
conn
|> assign(:user, otheruser)
|> put_req_header("content-type", "application/activity+json")
|> post("/users/#{user.nickname}/outbox", data)
|> post("/users/#{user.nickname}/outbox", activity)

assert json_response(conn, 403)
end

test "it inserts an incoming create activity into the database", %{conn: conn} do
data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
test "it inserts an incoming create activity into the database", %{
conn: conn,
activity: activity
} do
user = insert(:user)

conn =
result =
conn
|> assign(:user, user)
|> put_req_header("content-type", "application/activity+json")
|> post("/users/#{user.nickname}/outbox", data)

result = json_response(conn, 201)
|> post("/users/#{user.nickname}/outbox", activity)
|> json_response(201)

assert Activity.get_by_ap_id(result["id"])
assert result["object"]
assert %Object{data: object} = Object.normalize(result["object"])
assert object["content"] == activity["object"]["content"]
end

test "it rejects an incoming activity with bogus type", %{conn: conn} do
data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
test "it rejects anything beyond 'Note' creations", %{conn: conn, activity: activity} do
user = insert(:user)

data =
data
|> Map.put("type", "BadType")
activity =
activity
|> put_in(["object", "type"], "Benis")

_result =
conn
|> assign(:user, user)
|> put_req_header("content-type", "application/activity+json")
|> post("/users/#{user.nickname}/outbox", activity)
|> json_response(400)
end

test "it inserts an incoming sensitive activity into the database", %{
conn: conn,
activity: activity
} do
user = insert(:user)
object = Map.put(activity["object"], "sensitive", true)
activity = Map.put(activity, "object", object)

result =
conn
|> assign(:user, user)
|> put_req_header("content-type", "application/activity+json")
|> post("/users/#{user.nickname}/outbox", activity)
|> json_response(201)

assert Activity.get_by_ap_id(result["id"])
assert result["object"]
assert %Object{data: object} = Object.normalize(result["object"])
assert object["sensitive"] == activity["object"]["sensitive"]
assert object["content"] == activity["object"]["content"]
end

test "it rejects an incoming activity with bogus type", %{conn: conn, activity: activity} do
user = insert(:user)
activity = Map.put(activity, "type", "BadType")

conn =
conn
|> assign(:user, user)
|> put_req_header("content-type", "application/activity+json")
|> post("/users/#{user.nickname}/outbox", data)
|> post("/users/#{user.nickname}/outbox", activity)

assert json_response(conn, 400)
end


+ 33
- 4
test/web/activity_pub/activity_pub_test.exs View File

@@ -1351,15 +1351,44 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert Repo.aggregate(Object, :count, :id) == 0
end

clear_config([:instance, :federating])

test "creates a block activity" do
Config.put([:instance, :federating], true)
blocker = insert(:user)
blocked = insert(:user)

{:ok, activity} = ActivityPub.block(blocker, blocked)
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
{:ok, activity} = ActivityPub.block(blocker, blocked)

assert activity.data["type"] == "Block"
assert activity.data["actor"] == blocker.ap_id
assert activity.data["object"] == blocked.ap_id
assert activity.data["type"] == "Block"
assert activity.data["actor"] == blocker.ap_id
assert activity.data["object"] == blocked.ap_id

assert called(Pleroma.Web.Federator.publish(activity))
end
end

clear_config([:instance, :federating])
clear_config([:activitypub, :outgoing_blocks])

test "works with outgoing blocks disabled, but doesn't federate" do
Config.put([:instance, :federating], true)
Config.put([:activitypub, :outgoing_blocks], false)
blocker = insert(:user)
blocked = insert(:user)

with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
{:ok, activity} = ActivityPub.block(blocker, blocked)

assert activity.data["type"] == "Block"
assert activity.data["actor"] == blocker.ap_id
assert activity.data["object"] == blocked.ap_id

refute called(Pleroma.Web.Federator.publish(:_))
end
end

test "reverts unblock activity on error" do


+ 6
- 0
test/web/activity_pub/transmogrifier_test.exs View File

@@ -1120,6 +1120,12 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
follower = User.get_cached_by_id(follower.id)

assert User.following?(follower, followed) == true

follower = User.get_by_id(follower.id)
assert follower.following_count == 1

followed = User.get_by_id(followed.id)
assert followed.follower_count == 1
end

test "it fails for incoming accepts which cannot be correlated" do


+ 0
- 2
test/web/mastodon_api/controllers/suggestion_controller_test.exs View File

@@ -5,8 +5,6 @@
defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
use Pleroma.Web.ConnCase

alias Pleroma.Config

setup do: oauth_access(["read"])

test "returns empty result", %{conn: conn} do


+ 85
- 19
test/web/streamer/streamer_test.exs View File

@@ -17,11 +17,81 @@ defmodule Pleroma.Web.StreamerTest do

@moduletag needs_streamer: true, capture_log: true

@streamer_timeout 150
@streamer_timeout 300
@streamer_start_wait 10

clear_config([:instance, :skip_thread_containment])

describe "get_topic without an user" do
test "allows public" do
assert {:ok, "public"} = Streamer.get_topic("public", nil)
assert {:ok, "public:local"} = Streamer.get_topic("public:local", nil)
assert {:ok, "public:media"} = Streamer.get_topic("public:media", nil)
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil)
end

test "allows hashtag streams" do
assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", nil, %{"tag" => "cofe"})
end

test "disallows user streams" do
assert {:error, _} = Streamer.get_topic("user", nil)
assert {:error, _} = Streamer.get_topic("user:notification", nil)
assert {:error, _} = Streamer.get_topic("direct", nil)
end

test "disallows list streams" do
assert {:error, _} = Streamer.get_topic("list", nil, %{"list" => 42})
end
end

describe "get_topic with an user" do
setup do
user = insert(:user)
{:ok, %{user: user}}
end

test "allows public streams", %{user: user} do
assert {:ok, "public"} = Streamer.get_topic("public", user)
assert {:ok, "public:local"} = Streamer.get_topic("public:local", user)
assert {:ok, "public:media"} = Streamer.get_topic("public:media", user)
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", user)
end

test "allows user streams", %{user: user} do
expected_user_topic = "user:#{user.id}"
expected_notif_topic = "user:notification:#{user.id}"
expected_direct_topic = "direct:#{user.id}"
assert {:ok, ^expected_user_topic} = Streamer.get_topic("user", user)
assert {:ok, ^expected_notif_topic} = Streamer.get_topic("user:notification", user)
assert {:ok, ^expected_direct_topic} = Streamer.get_topic("direct", user)
end

test "allows hashtag streams", %{user: user} do
assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", user, %{"tag" => "cofe"})
end

test "disallows registering to an user stream", %{user: user} do
another_user = insert(:user)
assert {:error, _} = Streamer.get_topic("user:#{another_user.id}", user)
assert {:error, _} = Streamer.get_topic("user:notification:#{another_user.id}", user)
assert {:error, _} = Streamer.get_topic("direct:#{another_user.id}", user)
end

test "allows list stream that are owned by the user", %{user: user} do
{:ok, list} = List.create("Test", user)
assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
assert {:ok, _} = Streamer.get_topic("list", user, %{"list" => list.id})
end

test "disallows list stream that are not owned by the user", %{user: user} do
another_user = insert(:user)
{:ok, list} = List.create("Test", another_user)
assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
assert {:error, _} = Streamer.get_topic("list", user, %{"list" => list.id})
end
end

describe "user streams" do
setup do
user = insert(:user)
@@ -35,7 +105,7 @@ defmodule Pleroma.Web.StreamerTest do
assert_receive {:text, _}, @streamer_timeout
end)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"user",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -50,7 +120,7 @@ defmodule Pleroma.Web.StreamerTest do
assert_receive {:text, _}, @streamer_timeout
end)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"user:notification",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -70,7 +140,7 @@ defmodule Pleroma.Web.StreamerTest do

task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"user:notification",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -90,7 +160,7 @@ defmodule Pleroma.Web.StreamerTest do

task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"user:notification",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -110,7 +180,7 @@ defmodule Pleroma.Web.StreamerTest do

task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"user:notification",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -127,7 +197,7 @@ defmodule Pleroma.Web.StreamerTest do

Process.sleep(@streamer_start_wait)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"user:notification",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -415,14 +485,10 @@ defmodule Pleroma.Web.StreamerTest do
assert_receive {:text, _}, 1_000
end)

fake_socket = %StreamerSocket{
transport_pid: task.pid,
user: user_a
}

Streamer.add_socket(
"list:#{list.id}",
fake_socket
Streamer.get_topic_and_add_socket(
"list",
%{transport_pid: task.pid, assigns: %{user: user_a}},
%{"list" => list.id}
)

Worker.handle_call({:stream, "list", activity}, self(), %{})
@@ -497,7 +563,7 @@ defmodule Pleroma.Web.StreamerTest do

task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"user",
%{transport_pid: task.pid, assigns: %{user: user2}}
)
@@ -527,7 +593,7 @@ defmodule Pleroma.Web.StreamerTest do
assert last_status["pleroma"]["direct_conversation_id"] == participation.id
end)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"direct",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -561,7 +627,7 @@ defmodule Pleroma.Web.StreamerTest do

Process.sleep(@streamer_start_wait)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"direct",
%{transport_pid: task.pid, assigns: %{user: user}}
)
@@ -604,7 +670,7 @@ defmodule Pleroma.Web.StreamerTest do

Process.sleep(@streamer_start_wait)

Streamer.add_socket(
Streamer.get_topic_and_add_socket(
"direct",
%{transport_pid: task.pid, assigns: %{user: user}}
)


Loading…
Cancel
Save