Merge remote-tracking branch 'remotes/origin/develop' into 1505-threads-federation
# Conflicts: # CHANGELOG.md # config/config.exs
This commit is contained in:
commit
8f0ca19b9c
|
@ -74,6 +74,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- User settings: Add _This account is a_ option.
|
- User settings: Add _This account is a_ option.
|
||||||
- A new users admin digest email
|
- A new users admin digest email
|
||||||
- OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`).
|
- OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`).
|
||||||
|
- Add an option `authorized_fetch_mode` to require HTTP signatures for AP fetches.
|
||||||
- ActivityPub: support for `replies` collection (output for outgoing federation & fetching on incoming federation).
|
- ActivityPub: support for `replies` collection (output for outgoing federation & fetching on incoming federation).
|
||||||
<details>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
|
@ -116,6 +117,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Configuration: `feed.logo` option for tag feed.
|
- Configuration: `feed.logo` option for tag feed.
|
||||||
- Tag feed: `/tags/:tag.rss` - list public statuses by hashtag.
|
- Tag feed: `/tags/:tag.rss` - list public statuses by hashtag.
|
||||||
- Mastodon API: Add `reacted` property to `emoji_reactions`
|
- Mastodon API: Add `reacted` property to `emoji_reactions`
|
||||||
|
- Pleroma API: Add reactions for a single emoji.
|
||||||
- ActivityPub: `[:activitypub, :note_replies_output_limit]` setting sets the number of note self-replies to output on outgoing federation.
|
- ActivityPub: `[:activitypub, :note_replies_output_limit]` setting sets the number of note self-replies to output on outgoing federation.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,8 @@
|
||||||
outgoing_blocks: true,
|
outgoing_blocks: true,
|
||||||
follow_handshake_timeout: 500,
|
follow_handshake_timeout: 500,
|
||||||
note_replies_output_limit: 5,
|
note_replies_output_limit: 5,
|
||||||
sign_object_fetches: true
|
sign_object_fetches: true,
|
||||||
|
authorized_fetch_mode: false
|
||||||
|
|
||||||
config :pleroma, :streamer,
|
config :pleroma, :streamer,
|
||||||
workers: 3,
|
workers: 3,
|
||||||
|
@ -618,6 +619,8 @@
|
||||||
|
|
||||||
config :pleroma, configurable_from_database: false
|
config :pleroma, configurable_from_database: false
|
||||||
|
|
||||||
|
config :pleroma, Pleroma.Repo, parameters: [gin_fuzzy_search_limit: "500"]
|
||||||
|
|
||||||
# Import environment specific config. This must remain at the bottom
|
# Import environment specific config. This must remain at the bottom
|
||||||
# of this file so it overrides the configuration defined above.
|
# of this file so it overrides the configuration defined above.
|
||||||
import_config "#{Mix.env()}.exs"
|
import_config "#{Mix.env()}.exs"
|
||||||
|
|
|
@ -459,3 +459,16 @@ Emoji reactions work a lot like favourites do. They make it possible to react to
|
||||||
{"name": "☕", "count": 1, "me": false, "accounts": [{"id" => "abc..."}]}
|
{"name": "☕", "count": 1, "me": false, "accounts": [{"id" => "abc..."}]}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `GET /api/v1/pleroma/statuses/:id/reactions/:emoji`
|
||||||
|
### Get an object of emoji to account mappings with accounts that reacted to the post for a specific emoji`
|
||||||
|
* Method: `GET`
|
||||||
|
* Authentication: optional
|
||||||
|
* Params: None
|
||||||
|
* Response: JSON, a list of emoji/account list tuples
|
||||||
|
* Example Response:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{"name": "😀", "count": 2, "me": true, "accounts": [{"id" => "xyz.."...}, {"id" => "zyx..."}]}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
6. Run `sudo -Hu postgres pg_restore -d <pleroma_db> -v -1 </path/to/backup_location/pleroma.pgdump>`
|
6. Run `sudo -Hu postgres pg_restore -d <pleroma_db> -v -1 </path/to/backup_location/pleroma.pgdump>`
|
||||||
7. If you installed a newer Pleroma version, you should run `mix ecto.migrate`[^1]. This task performs database migrations, if there were any.
|
7. If you installed a newer Pleroma version, you should run `mix ecto.migrate`[^1]. This task performs database migrations, if there were any.
|
||||||
8. Restart the Pleroma service.
|
8. Restart the Pleroma service.
|
||||||
|
9. After you've restarted Pleroma, you will notice that postgres will take up more cpu resources than usual. A lot in fact. To fix this you must do a VACUUM ANLAYZE. This can also be done while the instance is still running like so:
|
||||||
|
$ sudo -u postgres psql pleroma_database_name
|
||||||
|
pleroma=# VACUUM ANALYZE;
|
||||||
[^1]: Prefix with `MIX_ENV=prod` to run it using the production config file.
|
[^1]: Prefix with `MIX_ENV=prod` to run it using the production config file.
|
||||||
|
|
||||||
## Remove
|
## Remove
|
||||||
|
|
|
@ -1,4 +1,21 @@
|
||||||
# Updating your instance
|
# Updating your instance
|
||||||
|
|
||||||
|
You should **always check the release notes/changelog** in case there are config deprecations, special update special update steps, etc.
|
||||||
|
|
||||||
|
Besides that, doing the following is generally enough:
|
||||||
|
|
||||||
|
## For OTP installations
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Download the new release
|
||||||
|
su pleroma -s $SHELL -lc "./bin/pleroma_ctl update"
|
||||||
|
|
||||||
|
# Migrate the database, you are advised to stop the instance before doing that
|
||||||
|
su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
|
||||||
|
```
|
||||||
|
|
||||||
|
## For from source installations (using git)
|
||||||
|
|
||||||
1. Go to the working directory of Pleroma (default is `/opt/pleroma`)
|
1. Go to the working directory of Pleroma (default is `/opt/pleroma`)
|
||||||
2. Run `git pull`. This pulls the latest changes from upstream.
|
2. Run `git pull`. This pulls the latest changes from upstream.
|
||||||
3. Run `mix deps.get`. This pulls in any new dependencies.
|
3. Run `mix deps.get`. This pulls in any new dependencies.
|
||||||
|
|
|
@ -143,10 +143,11 @@ config :pleroma, :mrf_user_allowlist,
|
||||||
* `:reject` rejects the message entirely
|
* `:reject` rejects the message entirely
|
||||||
|
|
||||||
### :activitypub
|
### :activitypub
|
||||||
* ``unfollow_blocked``: Whether blocks result in people getting unfollowed
|
* `unfollow_blocked`: Whether blocks result in people getting unfollowed
|
||||||
* ``outgoing_blocks``: Whether to federate blocks to other instances
|
* `outgoing_blocks`: Whether to federate blocks to other instances
|
||||||
* ``deny_follow_blocked``: Whether to disallow following an account that has blocked the user in question
|
* `deny_follow_blocked`: Whether to disallow following an account that has blocked the user in question
|
||||||
* ``sign_object_fetches``: Sign object fetches with HTTP signatures
|
* `sign_object_fetches`: Sign object fetches with HTTP signatures
|
||||||
|
* `authorized_fetch_mode`: Require HTTP signatures for AP fetches
|
||||||
|
|
||||||
### :fetch_initial_posts
|
### :fetch_initial_posts
|
||||||
* `enabled`: if enabled, when a new user is federated with, fetch some of their latest posts
|
* `enabled`: if enabled, when a new user is federated with, fetch some of their latest posts
|
||||||
|
|
|
@ -259,19 +259,14 @@ su pleroma -s $SHELL -lc "./bin/pleroma_ctl user new joeuser joeuser@sld.tld --a
|
||||||
```
|
```
|
||||||
This will create an account withe the username of 'joeuser' with the email address of joeuser@sld.tld, and set that user's account as an admin. This will result in a link that you can paste into the browser, which logs you in and enables you to set the password.
|
This will create an account withe the username of 'joeuser' with the email address of joeuser@sld.tld, and set that user's account as an admin. This will result in a link that you can paste into the browser, which logs you in and enables you to set the password.
|
||||||
|
|
||||||
### Updating
|
|
||||||
Generally, doing the following is enough:
|
|
||||||
```sh
|
|
||||||
# Download the new release
|
|
||||||
su pleroma -s $SHELL -lc "./bin/pleroma_ctl update"
|
|
||||||
|
|
||||||
# Migrate the database, you are advised to stop the instance before doing that
|
|
||||||
su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
|
|
||||||
```
|
|
||||||
But you should **always check the release notes/changelog** in case there are config deprecations, special update steps, etc.
|
|
||||||
|
|
||||||
## Further reading
|
## Further reading
|
||||||
|
|
||||||
* [Backup your instance](../administration/backup.md)
|
* [Backup your instance](../administration/backup.md)
|
||||||
* [Hardening your instance](../configuration/hardening.md)
|
* [Hardening your instance](../configuration/hardening.md)
|
||||||
* [How to activate mediaproxy](../configuration/howto_mediaproxy.md)
|
* [How to activate mediaproxy](../configuration/howto_mediaproxy.md)
|
||||||
|
* [Updating your instance](../administration/updating.md)
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
|
||||||
|
Questions about the installation or didn’t it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
|
defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
import Phoenix.Controller, only: [get_format: 1, text: 2]
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def init(options) do
|
def init(options) do
|
||||||
|
@ -15,25 +16,27 @@ def call(%{assigns: %{valid_signature: true}} = conn, _opts) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(conn, _opts) do
|
def call(conn, _opts) do
|
||||||
headers = get_req_header(conn, "signature")
|
if get_format(conn) == "activity+json" do
|
||||||
signature = Enum.at(headers, 0)
|
conn
|
||||||
|
|> maybe_assign_valid_signature()
|
||||||
|
|> maybe_require_signature()
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if signature do
|
defp maybe_assign_valid_signature(conn) do
|
||||||
|
if has_signature_header?(conn) do
|
||||||
# set (request-target) header to the appropriate value
|
# set (request-target) header to the appropriate value
|
||||||
# we also replace the digest header with the one we computed
|
# we also replace the digest header with the one we computed
|
||||||
conn =
|
request_target = String.downcase("#{conn.method}") <> " #{conn.request_path}"
|
||||||
conn
|
|
||||||
|> put_req_header(
|
|
||||||
"(request-target)",
|
|
||||||
String.downcase("#{conn.method}") <> " #{conn.request_path}"
|
|
||||||
)
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
if conn.assigns[:digest] do
|
conn
|
||||||
conn
|
|> put_req_header("(request-target)", request_target)
|
||||||
|> put_req_header("digest", conn.assigns[:digest])
|
|> case do
|
||||||
else
|
%{assigns: %{digest: digest}} = conn -> put_req_header(conn, "digest", digest)
|
||||||
conn
|
conn -> conn
|
||||||
end
|
end
|
||||||
|
|
||||||
assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn))
|
assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn))
|
||||||
|
@ -42,4 +45,21 @@ def call(conn, _opts) do
|
||||||
conn
|
conn
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp has_signature_header?(conn) do
|
||||||
|
conn |> get_req_header("signature") |> Enum.at(0, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_require_signature(%{assigns: %{valid_signature: true}} = conn), do: conn
|
||||||
|
|
||||||
|
defp maybe_require_signature(conn) do
|
||||||
|
if Pleroma.Config.get([:activitypub, :authorized_fetch_mode], false) do
|
||||||
|
conn
|
||||||
|
|> put_status(:unauthorized)
|
||||||
|
|> text("Request not signed")
|
||||||
|
|> halt()
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -41,24 +41,29 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
|
||||||
|
|
||||||
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
|
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
|
||||||
|
|
||||||
def emoji_reactions_by(%{assigns: %{user: user}} = conn, %{"id" => activity_id}) do
|
def emoji_reactions_by(%{assigns: %{user: user}} = conn, %{"id" => activity_id} = params) do
|
||||||
with %Activity{} = activity <- Activity.get_by_id_with_object(activity_id),
|
with %Activity{} = activity <- Activity.get_by_id_with_object(activity_id),
|
||||||
%Object{data: %{"reactions" => emoji_reactions}} when is_list(emoji_reactions) <-
|
%Object{data: %{"reactions" => emoji_reactions}} when is_list(emoji_reactions) <-
|
||||||
Object.normalize(activity) do
|
Object.normalize(activity) do
|
||||||
reactions =
|
reactions =
|
||||||
emoji_reactions
|
emoji_reactions
|
||||||
|> Enum.map(fn [emoji, user_ap_ids] ->
|
|> Enum.map(fn [emoji, user_ap_ids] ->
|
||||||
users =
|
if params["emoji"] && params["emoji"] != emoji do
|
||||||
Enum.map(user_ap_ids, &User.get_cached_by_ap_id/1)
|
nil
|
||||||
|> Enum.filter(& &1)
|
else
|
||||||
|
users =
|
||||||
|
Enum.map(user_ap_ids, &User.get_cached_by_ap_id/1)
|
||||||
|
|> Enum.filter(& &1)
|
||||||
|
|
||||||
%{
|
%{
|
||||||
name: emoji,
|
name: emoji,
|
||||||
count: length(users),
|
count: length(users),
|
||||||
accounts: AccountView.render("index.json", %{users: users, for: user, as: :user}),
|
accounts: AccountView.render("index.json", %{users: users, for: user, as: :user}),
|
||||||
me: !!(user && user.ap_id in user_ap_ids)
|
me: !!(user && user.ap_id in user_ap_ids)
|
||||||
}
|
}
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|> Enum.filter(& &1)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> json(reactions)
|
|> json(reactions)
|
||||||
|
|
|
@ -271,6 +271,7 @@ defmodule Pleroma.Web.Router do
|
||||||
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
||||||
pipe_through(:api)
|
pipe_through(:api)
|
||||||
|
|
||||||
|
get("/statuses/:id/reactions/:emoji", PleromaAPIController, :emoji_reactions_by)
|
||||||
get("/statuses/:id/reactions", PleromaAPIController, :emoji_reactions_by)
|
get("/statuses/:id/reactions", PleromaAPIController, :emoji_reactions_by)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
|
defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
|
||||||
|
@ -69,7 +69,7 @@ defp is_status?(acct) do
|
||||||
def do_follow(%{assigns: %{user: %User{} = user}} = conn, %{"user" => %{"id" => id}}) do
|
def do_follow(%{assigns: %{user: %User{} = user}} = conn, %{"user" => %{"id" => id}}) do
|
||||||
with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
|
with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
|
||||||
{:ok, _, _, _} <- CommonAPI.follow(user, followee) do
|
{:ok, _, _, _} <- CommonAPI.follow(user, followee) do
|
||||||
render(conn, "followed.html", %{error: false})
|
redirect(conn, to: "/users/#{followee.id}")
|
||||||
else
|
else
|
||||||
error ->
|
error ->
|
||||||
handle_follow_error(conn, error)
|
handle_follow_error(conn, error)
|
||||||
|
@ -80,7 +80,7 @@ def do_follow(conn, %{"authorization" => %{"name" => _, "password" => _, "id" =>
|
||||||
with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
|
with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
|
||||||
{_, {:ok, user}, _} <- {:auth, Authenticator.get_user(conn), followee},
|
{_, {:ok, user}, _} <- {:auth, Authenticator.get_user(conn), followee},
|
||||||
{:ok, _, _, _} <- CommonAPI.follow(user, followee) do
|
{:ok, _, _, _} <- CommonAPI.follow(user, followee) do
|
||||||
render(conn, "followed.html", %{error: false})
|
redirect(conn, to: "/users/#{followee.id}")
|
||||||
else
|
else
|
||||||
error ->
|
error ->
|
||||||
handle_follow_error(conn, error)
|
handle_follow_error(conn, error)
|
||||||
|
|
|
@ -17,7 +17,11 @@ def up do
|
||||||
Repo.stream(query)
|
Repo.stream(query)
|
||||||
|> Enum.each(fn %{id: user_id, bookmarks: bookmarks} ->
|
|> Enum.each(fn %{id: user_id, bookmarks: bookmarks} ->
|
||||||
Enum.each(bookmarks, fn ap_id ->
|
Enum.each(bookmarks, fn ap_id ->
|
||||||
activity = Activity.get_create_by_object_ap_id(ap_id)
|
activity =
|
||||||
|
ap_id
|
||||||
|
|> Activity.create_by_object_ap_id()
|
||||||
|
|> Repo.one()
|
||||||
|
|
||||||
unless is_nil(activity), do: {:ok, _} = Bookmark.create(user_id, activity.id)
|
unless is_nil(activity), do: {:ok, _} = Bookmark.create(user_id, activity.id)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
defmodule Pleroma.Repo.Migrations.AddFollowingAddressFromSourceData do
|
defmodule Pleroma.Repo.Migrations.AddFollowingAddressFromSourceData do
|
||||||
use Ecto.Migration
|
|
||||||
import Ecto.Query
|
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
import Ecto.Query
|
||||||
|
require Logger
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
def change do
|
def change do
|
||||||
query =
|
query =
|
||||||
|
@ -19,6 +20,9 @@ def change do
|
||||||
:following_address
|
:following_address
|
||||||
])
|
])
|
||||||
|> Pleroma.Repo.update()
|
|> Pleroma.Repo.update()
|
||||||
|
|
||||||
|
user ->
|
||||||
|
Logger.warn("User #{user.id} / #{user.nickname} does not seem to have source_data")
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do
|
||||||
use Ecto.Migration
|
use Ecto.Migration
|
||||||
|
|
||||||
def change do
|
def change do
|
||||||
|
execute("update users set info = '{}' where info is null")
|
||||||
|
|
||||||
execute(
|
execute(
|
||||||
"update users set info = safe_jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true"
|
"update users set info = safe_jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true"
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do
|
||||||
alias Pleroma.Web.Plugs.HTTPSignaturePlug
|
alias Pleroma.Web.Plugs.HTTPSignaturePlug
|
||||||
|
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
import Phoenix.Controller, only: [put_format: 2]
|
||||||
import Mock
|
import Mock
|
||||||
|
|
||||||
test "it call HTTPSignatures to check validity if the actor sighed it" do
|
test "it call HTTPSignatures to check validity if the actor sighed it" do
|
||||||
|
@ -20,10 +21,69 @@ test "it call HTTPSignatures to check validity if the actor sighed it" do
|
||||||
"signature",
|
"signature",
|
||||||
"keyId=\"http://mastodon.example.org/users/admin#main-key"
|
"keyId=\"http://mastodon.example.org/users/admin#main-key"
|
||||||
)
|
)
|
||||||
|
|> put_format("activity+json")
|
||||||
|> HTTPSignaturePlug.call(%{})
|
|> HTTPSignaturePlug.call(%{})
|
||||||
|
|
||||||
assert conn.assigns.valid_signature == true
|
assert conn.assigns.valid_signature == true
|
||||||
|
assert conn.halted == false
|
||||||
assert called(HTTPSignatures.validate_conn(:_))
|
assert called(HTTPSignatures.validate_conn(:_))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "requires a signature when `authorized_fetch_mode` is enabled" do
|
||||||
|
setup do
|
||||||
|
Pleroma.Config.put([:activitypub, :authorized_fetch_mode], true)
|
||||||
|
|
||||||
|
on_exit(fn ->
|
||||||
|
Pleroma.Config.put([:activitypub, :authorized_fetch_mode], false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
params = %{"actor" => "http://mastodon.example.org/users/admin"}
|
||||||
|
conn = build_conn(:get, "/doesntmattter", params) |> put_format("activity+json")
|
||||||
|
|
||||||
|
[conn: conn]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "when signature header is present", %{conn: conn} do
|
||||||
|
with_mock HTTPSignatures, validate_conn: fn _ -> false end do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header(
|
||||||
|
"signature",
|
||||||
|
"keyId=\"http://mastodon.example.org/users/admin#main-key"
|
||||||
|
)
|
||||||
|
|> HTTPSignaturePlug.call(%{})
|
||||||
|
|
||||||
|
assert conn.assigns.valid_signature == false
|
||||||
|
assert conn.halted == true
|
||||||
|
assert conn.status == 401
|
||||||
|
assert conn.state == :sent
|
||||||
|
assert conn.resp_body == "Request not signed"
|
||||||
|
assert called(HTTPSignatures.validate_conn(:_))
|
||||||
|
end
|
||||||
|
|
||||||
|
with_mock HTTPSignatures, validate_conn: fn _ -> true end do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header(
|
||||||
|
"signature",
|
||||||
|
"keyId=\"http://mastodon.example.org/users/admin#main-key"
|
||||||
|
)
|
||||||
|
|> HTTPSignaturePlug.call(%{})
|
||||||
|
|
||||||
|
assert conn.assigns.valid_signature == true
|
||||||
|
assert conn.halted == false
|
||||||
|
assert called(HTTPSignatures.validate_conn(:_))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "halts the connection when `signature` header is not present", %{conn: conn} do
|
||||||
|
conn = HTTPSignaturePlug.call(conn, %{})
|
||||||
|
assert conn.assigns[:valid_signature] == nil
|
||||||
|
assert conn.halted == true
|
||||||
|
assert conn.status == 401
|
||||||
|
assert conn.state == :sent
|
||||||
|
assert conn.resp_body == "Request not signed"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,6 +96,32 @@ test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert result == []
|
||||||
|
|
||||||
|
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||||
|
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
|
||||||
|
|
||||||
|
result =
|
||||||
|
conn
|
||||||
|
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
[%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result
|
||||||
|
|
||||||
|
assert represented_user["id"] == other_user.id
|
||||||
|
end
|
||||||
|
|
||||||
test "/api/v1/pleroma/conversations/:id" do
|
test "/api/v1/pleroma/conversations/:id" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
%{user: other_user, conn: conn} = oauth_access(["read:statuses"])
|
%{user: other_user, conn: conn} = oauth_access(["read:statuses"])
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Pleroma: A lightweight social networking server
|
# Pleroma: A lightweight social networking server
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
|
defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
|
||||||
|
@ -92,15 +92,13 @@ test "follows user", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
user2 = insert(:user)
|
user2 = insert(:user)
|
||||||
|
|
||||||
response =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
|
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
|
||||||
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
|
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
|
||||||
|> response(200)
|
|
||||||
|
|
||||||
assert response =~ "Account followed!"
|
assert redirected_to(conn) == "/users/#{user2.id}"
|
||||||
assert user2.follower_address in User.following(user)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns error when user is deactivated", %{conn: conn} do
|
test "returns error when user is deactivated", %{conn: conn} do
|
||||||
|
@ -149,14 +147,13 @@ test "returns success result when user already in followers", %{conn: conn} do
|
||||||
user2 = insert(:user)
|
user2 = insert(:user)
|
||||||
{:ok, _, _, _} = CommonAPI.follow(user, user2)
|
{:ok, _, _, _} = CommonAPI.follow(user, user2)
|
||||||
|
|
||||||
response =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> assign(:user, refresh_record(user))
|
|> assign(:user, refresh_record(user))
|
||||||
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
|
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
|
||||||
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
|
|> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
|
||||||
|> response(200)
|
|
||||||
|
|
||||||
assert response =~ "Account followed!"
|
assert redirected_to(conn) == "/users/#{user2.id}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -165,14 +162,13 @@ test "follows", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
user2 = insert(:user)
|
user2 = insert(:user)
|
||||||
|
|
||||||
response =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> post(remote_follow_path(conn, :do_follow), %{
|
|> post(remote_follow_path(conn, :do_follow), %{
|
||||||
"authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
|
"authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
|
||||||
})
|
})
|
||||||
|> response(200)
|
|
||||||
|
|
||||||
assert response =~ "Account followed!"
|
assert redirected_to(conn) == "/users/#{user2.id}"
|
||||||
assert user2.follower_address in User.following(user)
|
assert user2.follower_address in User.following(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue