Compare commits
29 Commits
6e91e5c0cb
...
54d646c2fe
Author | SHA1 | Date |
---|---|---|
Rachel Fae Fox (foxiepaws) | 54d646c2fe | |
Rachel Fae Fox (foxiepaws) | 6283705806 | |
kaniini | f9a0014681 | |
kaniini | 1485d75f3c | |
Maksim | b6b748d3e7 | |
kaniini | e2c39e1cc0 | |
aries | 129078eddc | |
Ariadne Conill | 7bb50bfccc | |
Ariadne Conill | 1345e0c2bf | |
kaniini | 0e502cb836 | |
tallship | cffe8229a5 | |
kaniini | a51ee5fae5 | |
Ariadne Conill | 399acd4c42 | |
Bradley D. Thornton | cdecef2a08 | |
Ariadne Conill | b2a8ccf37f | |
kaniini | 1e48af9acf | |
kaniini | 60b54ee64a | |
Ariadne Conill | f84fb340b7 | |
Ariadne Conill | 1e3aff6ef1 | |
kaniini | 348307ec19 | |
Eugenij | 4bf2bb9cff | |
Ariadne Conill | c119835102 | |
Ariadne Conill | 3d23a12d75 | |
Ariadne Conill | cf9cb953d5 | |
Ariadne Conill | d930e5d5c3 | |
Ariadne Conill | 62e5ff624e | |
Ariadne Conill | 0a6f6e1b5b | |
Ariadne Conill | a9d6a12bb3 | |
Ariadne Conill | 4885473be2 |
|
@ -43,6 +43,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Configuration: Pleroma.Plugs.RateLimiter `bucket_name`, `params` options.
|
- Configuration: Pleroma.Plugs.RateLimiter `bucket_name`, `params` options.
|
||||||
- Addressable lists
|
- Addressable lists
|
||||||
- Twitter API: added rate limit for `/api/account/password_reset` endpoint.
|
- Twitter API: added rate limit for `/api/account/password_reset` endpoint.
|
||||||
|
- ActivityPub: Add an internal service actor for fetching ActivityPub objects.
|
||||||
|
- ActivityPub: Optional signing of ActivityPub object fetches.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
|
- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
|
||||||
|
|
|
@ -305,7 +305,8 @@ config :pleroma, :activitypub,
|
||||||
accept_blocks: true,
|
accept_blocks: true,
|
||||||
unfollow_blocked: true,
|
unfollow_blocked: true,
|
||||||
outgoing_blocks: true,
|
outgoing_blocks: true,
|
||||||
follow_handshake_timeout: 500
|
follow_handshake_timeout: 500,
|
||||||
|
sign_object_fetches: true
|
||||||
|
|
||||||
config :pleroma, :user, deny_follow_blocked: true
|
config :pleroma, :user, deny_follow_blocked: true
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ config :pleroma, :instance,
|
||||||
skip_thread_containment: false,
|
skip_thread_containment: false,
|
||||||
federating: false
|
federating: false
|
||||||
|
|
||||||
|
config :pleroma, :activitypub, sign_object_fetches: false
|
||||||
|
|
||||||
# Configure your database
|
# Configure your database
|
||||||
config :pleroma, Pleroma.Repo,
|
config :pleroma, Pleroma.Repo,
|
||||||
adapter: Ecto.Adapters.Postgres,
|
adapter: Ecto.Adapters.Postgres,
|
||||||
|
|
|
@ -31,6 +31,7 @@ Feel free to contact us to be added to this list!
|
||||||
- Features: No Streaming
|
- Features: No Streaming
|
||||||
|
|
||||||
### Fedilab
|
### Fedilab
|
||||||
|
- Homepage: <https://fedilab.app/>
|
||||||
- Source Code: <https://gitlab.com/tom79/mastalab/>
|
- Source Code: <https://gitlab.com/tom79/mastalab/>
|
||||||
- Contact: [@tom79@mastodon.social](https://mastodon.social/users/tom79)
|
- Contact: [@tom79@mastodon.social](https://mastodon.social/users/tom79)
|
||||||
- Platforms: Android
|
- Platforms: Android
|
||||||
|
|
|
@ -332,6 +332,7 @@ This will make Pleroma listen on `127.0.0.1` port `8080` and generate urls start
|
||||||
* ``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
|
||||||
|
|
||||||
## :http_security
|
## :http_security
|
||||||
* ``enabled``: Whether the managed content security policy is enabled
|
* ``enabled``: Whether the managed content security policy is enabled
|
||||||
|
|
|
@ -24,7 +24,9 @@ If you came here from one of the installation guides, take a look at the example
|
||||||
```
|
```
|
||||||
config :pleroma, :media_proxy,
|
config :pleroma, :media_proxy,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
redirect_on_failure: true
|
proxy_opts: [
|
||||||
|
redirect_on_failure: true
|
||||||
|
]
|
||||||
#base_url: "https://cache.pleroma.social"
|
#base_url: "https://cache.pleroma.social"
|
||||||
```
|
```
|
||||||
If you want to use a subdomain to serve the files, uncomment `base_url`, change the url and add a comma after `true` in the previous line.
|
If you want to use a subdomain to serve the files, uncomment `base_url`, change the url and add a comma after `true` in the previous line.
|
||||||
|
|
|
@ -242,6 +242,14 @@ So for example, if the task is `mix pleroma.user set admin --admin`, you should
|
||||||
```sh
|
```sh
|
||||||
su pleroma -s $SHELL -lc "./bin/pleroma_ctl user set admin --admin"
|
su pleroma -s $SHELL -lc "./bin/pleroma_ctl user set admin --admin"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Create your first user and set as admin
|
||||||
|
```sh
|
||||||
|
cd /opt/pleroma/bin
|
||||||
|
su pleroma -s $SHELL -lc "./bin/pleroma_ctl user new joeuser joeuser@sld.tld --admin"
|
||||||
|
```
|
||||||
|
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
|
### Updating
|
||||||
Generally, doing the following is enough:
|
Generally, doing the following is enough:
|
||||||
```sh
|
```sh
|
||||||
|
|
|
@ -140,6 +140,11 @@ defmodule Pleroma.Application do
|
||||||
id: :federator_init,
|
id: :federator_init,
|
||||||
start: {Task, :start_link, [&Pleroma.Web.Federator.init/0]},
|
start: {Task, :start_link, [&Pleroma.Web.Federator.init/0]},
|
||||||
restart: :temporary
|
restart: :temporary
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
id: :internal_fetch_init,
|
||||||
|
start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]},
|
||||||
|
restart: :temporary
|
||||||
}
|
}
|
||||||
] ++
|
] ++
|
||||||
streamer_child() ++
|
streamer_child() ++
|
||||||
|
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Object.Fetcher do
|
||||||
alias Pleroma.HTTP
|
alias Pleroma.HTTP
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Object.Containment
|
alias Pleroma.Object.Containment
|
||||||
|
alias Pleroma.Signature
|
||||||
|
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
alias Pleroma.Web.OStatus
|
alias Pleroma.Web.OStatus
|
||||||
|
|
||||||
|
@ -82,15 +84,52 @@ defmodule Pleroma.Object.Fetcher do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp make_signature(id, date) do
|
||||||
|
uri = URI.parse(id)
|
||||||
|
|
||||||
|
signature =
|
||||||
|
InternalFetchActor.get_actor()
|
||||||
|
|> Signature.sign(%{
|
||||||
|
"(request-target)": "get #{uri.path}",
|
||||||
|
host: uri.host,
|
||||||
|
date: date
|
||||||
|
})
|
||||||
|
|
||||||
|
[{:Signature, signature}]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp sign_fetch(headers, id, date) do
|
||||||
|
if Pleroma.Config.get([:activitypub, :sign_object_fetches]) do
|
||||||
|
headers ++ make_signature(id, date)
|
||||||
|
else
|
||||||
|
headers
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_date_fetch(headers, date) do
|
||||||
|
if Pleroma.Config.get([:activitypub, :sign_object_fetches]) do
|
||||||
|
headers ++ [{:Date, date}]
|
||||||
|
else
|
||||||
|
headers
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def fetch_and_contain_remote_object_from_id(id) do
|
def fetch_and_contain_remote_object_from_id(id) do
|
||||||
Logger.info("Fetching object #{id} via AP")
|
Logger.info("Fetching object #{id} via AP")
|
||||||
|
|
||||||
|
date =
|
||||||
|
NaiveDateTime.utc_now()
|
||||||
|
|> Timex.format!("{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT")
|
||||||
|
|
||||||
|
headers =
|
||||||
|
[{:Accept, "application/activity+json"}]
|
||||||
|
|> maybe_date_fetch(date)
|
||||||
|
|> sign_fetch(id, date)
|
||||||
|
|
||||||
|
Logger.debug("Fetch headers: #{inspect(headers)}")
|
||||||
|
|
||||||
with true <- String.starts_with?(id, "http"),
|
with true <- String.starts_with?(id, "http"),
|
||||||
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
{:ok, %{body: body, status: code}} when code in 200..299 <- HTTP.get(id, headers),
|
||||||
HTTP.get(
|
|
||||||
id,
|
|
||||||
[{:Accept, "application/activity+json"}]
|
|
||||||
),
|
|
||||||
{:ok, data} <- Jason.decode(body),
|
{:ok, data} <- Jason.decode(body),
|
||||||
:ok <- Containment.contain_origin_from_id(id, data) do
|
:ok <- Containment.contain_origin_from_id(id, data) do
|
||||||
{:ok, data}
|
{:ok, data}
|
||||||
|
|
|
@ -8,10 +8,16 @@ defmodule Pleroma.Signature do
|
||||||
alias Pleroma.Keys
|
alias Pleroma.Keys
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
|
||||||
|
defp key_id_to_actor_id(key_id) do
|
||||||
|
URI.parse(key_id)
|
||||||
|
|> Map.put(:fragment, nil)
|
||||||
|
|> URI.to_string()
|
||||||
|
end
|
||||||
|
|
||||||
def fetch_public_key(conn) do
|
def fetch_public_key(conn) do
|
||||||
with actor_id <- Utils.get_ap_id(conn.params["actor"]),
|
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
|
||||||
|
actor_id <- key_id_to_actor_id(kid),
|
||||||
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
|
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
|
||||||
{:ok, public_key}
|
{:ok, public_key}
|
||||||
else
|
else
|
||||||
|
@ -21,7 +27,8 @@ defmodule Pleroma.Signature do
|
||||||
end
|
end
|
||||||
|
|
||||||
def refetch_public_key(conn) do
|
def refetch_public_key(conn) do
|
||||||
with actor_id <- Utils.get_ap_id(conn.params["actor"]),
|
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
|
||||||
|
actor_id <- key_id_to_actor_id(kid),
|
||||||
{:ok, _user} <- ActivityPub.make_user_from_ap_id(actor_id),
|
{:ok, _user} <- ActivityPub.make_user_from_ap_id(actor_id),
|
||||||
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
|
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
|
||||||
{:ok, public_key}
|
{:ok, public_key}
|
||||||
|
|
|
@ -68,7 +68,14 @@ defmodule Pleroma.Uploaders.Uploader do
|
||||||
{:error, error}
|
{:error, error}
|
||||||
end
|
end
|
||||||
after
|
after
|
||||||
30_000 -> {:error, dgettext("errors", "Uploader callback timeout")}
|
callback_timeout() -> {:error, dgettext("errors", "Uploader callback timeout")}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp callback_timeout do
|
||||||
|
case Mix.env() do
|
||||||
|
:test -> 1_000
|
||||||
|
_ -> 30_000
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1157,19 +1157,18 @@ defmodule Pleroma.User do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_or_create_instance_user do
|
@doc "Creates an internal service actor by URI if missing. Optionally takes nickname for addressing."
|
||||||
relay_uri = "#{Pleroma.Web.Endpoint.url()}/relay"
|
def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do
|
||||||
|
if user = get_cached_by_ap_id(uri) do
|
||||||
if user = get_cached_by_ap_id(relay_uri) do
|
|
||||||
user
|
user
|
||||||
else
|
else
|
||||||
changes =
|
changes =
|
||||||
%User{info: %User.Info{}}
|
%User{info: %User.Info{}}
|
||||||
|> cast(%{}, [:ap_id, :nickname, :local])
|
|> cast(%{}, [:ap_id, :nickname, :local])
|
||||||
|> put_change(:ap_id, relay_uri)
|
|> put_change(:ap_id, uri)
|
||||||
|> put_change(:nickname, nil)
|
|> put_change(:nickname, nickname)
|
||||||
|> put_change(:local, true)
|
|> put_change(:local, true)
|
||||||
|> put_change(:follower_address, relay_uri <> "/followers")
|
|> put_change(:follower_address, uri <> "/followers")
|
||||||
|
|
||||||
{:ok, user} = Repo.insert(changes)
|
{:ok, user} = Repo.insert(changes)
|
||||||
user
|
user
|
||||||
|
@ -1411,4 +1410,8 @@ defmodule Pleroma.User do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp put_password_hash(changeset), do: changeset
|
defp put_password_hash(changeset), do: changeset
|
||||||
|
|
||||||
|
def is_internal_user?(%User{nickname: nil}), do: true
|
||||||
|
def is_internal_user?(%User{local: true, nickname: "internal." <> _}), do: true
|
||||||
|
def is_internal_user?(_), do: false
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
||||||
alias Pleroma.Object.Fetcher
|
alias Pleroma.Object.Fetcher
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||||
alias Pleroma.Web.ActivityPub.ObjectView
|
alias Pleroma.Web.ActivityPub.ObjectView
|
||||||
alias Pleroma.Web.ActivityPub.Relay
|
alias Pleroma.Web.ActivityPub.Relay
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
@ -206,9 +207,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
||||||
json(conn, dgettext("errors", "error"))
|
json(conn, dgettext("errors", "error"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def relay(conn, _params) do
|
defp represent_service_actor(%User{} = user, conn) do
|
||||||
with %User{} = user <- Relay.get_actor(),
|
with {:ok, user} <- User.ensure_keys_present(user) do
|
||||||
{:ok, user} <- User.ensure_keys_present(user) do
|
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|> json(UserView.render("user.json", %{user: user}))
|
|> json(UserView.render("user.json", %{user: user}))
|
||||||
|
@ -217,6 +217,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp represent_service_actor(nil, _), do: {:error, :not_found}
|
||||||
|
|
||||||
|
def relay(conn, _params) do
|
||||||
|
Relay.get_actor()
|
||||||
|
|> represent_service_actor(conn)
|
||||||
|
end
|
||||||
|
|
||||||
|
def internal_fetch(conn, _params) do
|
||||||
|
InternalFetchActor.get_actor()
|
||||||
|
|> represent_service_actor(conn)
|
||||||
|
end
|
||||||
|
|
||||||
def whoami(%{assigns: %{user: %User{} = user}} = conn, _params) do
|
def whoami(%{assigns: %{user: %User{} = user}} = conn, _params) do
|
||||||
conn
|
conn
|
||||||
|> put_resp_header("content-type", "application/activity+json")
|
|> put_resp_header("content-type", "application/activity+json")
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ActivityPub.InternalFetchActor do
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
def init do
|
||||||
|
# Wait for everything to settle.
|
||||||
|
Process.sleep(1000 * 5)
|
||||||
|
get_actor()
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_actor do
|
||||||
|
"#{Pleroma.Web.Endpoint.url()}/internal/fetch"
|
||||||
|
|> User.get_or_create_service_actor_by_ap_id("internal.fetch")
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,8 @@ defmodule Pleroma.Web.ActivityPub.Relay do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def get_actor do
|
def get_actor do
|
||||||
User.get_or_create_instance_user()
|
"#{Pleroma.Web.Endpoint.url()}/relay"
|
||||||
|
|> User.get_or_create_service_actor_by_ap_id()
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow(target_instance) do
|
def follow(target_instance) do
|
||||||
|
|
|
@ -31,8 +31,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
||||||
|
|
||||||
def render("endpoints.json", _), do: %{}
|
def render("endpoints.json", _), do: %{}
|
||||||
|
|
||||||
# the instance itself is not a Person, but instead an Application
|
def render("service.json", %{user: user}) do
|
||||||
def render("user.json", %{user: %{nickname: nil} = user}) do
|
|
||||||
{:ok, user} = User.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
|
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
|
||||||
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
|
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
|
||||||
|
@ -47,7 +46,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
||||||
"followers" => "#{user.ap_id}/followers",
|
"followers" => "#{user.ap_id}/followers",
|
||||||
"inbox" => "#{user.ap_id}/inbox",
|
"inbox" => "#{user.ap_id}/inbox",
|
||||||
"name" => "Pleroma",
|
"name" => "Pleroma",
|
||||||
"summary" => "Virtual actor for Pleroma relay",
|
"summary" =>
|
||||||
|
"An internal service actor for this Pleroma instance. No user-serviceable parts inside.",
|
||||||
"url" => user.ap_id,
|
"url" => user.ap_id,
|
||||||
"manuallyApprovesFollowers" => false,
|
"manuallyApprovesFollowers" => false,
|
||||||
"publicKey" => %{
|
"publicKey" => %{
|
||||||
|
@ -60,6 +60,13 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
||||||
|> Map.merge(Utils.make_json_ld_header())
|
|> Map.merge(Utils.make_json_ld_header())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# the instance itself is not a Person, but instead an Application
|
||||||
|
def render("user.json", %{user: %User{nickname: nil} = user}),
|
||||||
|
do: render("service.json", %{user: user})
|
||||||
|
|
||||||
|
def render("user.json", %{user: %User{nickname: "internal." <> _} = user}),
|
||||||
|
do: render("service.json", %{user: user})
|
||||||
|
|
||||||
def render("user.json", %{user: user}) do
|
def render("user.json", %{user: user}) do
|
||||||
{:ok, user} = User.ensure_keys_present(user)
|
{:ok, user} = User.ensure_keys_present(user)
|
||||||
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
|
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
|
||||||
|
|
|
@ -1826,10 +1826,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
||||||
|> json("")
|
|> json("")
|
||||||
else
|
else
|
||||||
{:error, "unknown user"} ->
|
{:error, "unknown user"} ->
|
||||||
put_status(conn, :not_found)
|
send_resp(conn, :not_found, "")
|
||||||
|
|
||||||
{:error, _} ->
|
{:error, _} ->
|
||||||
put_status(conn, :bad_request)
|
send_resp(conn, :bad_request, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -586,7 +586,7 @@ defmodule Pleroma.Web.Router do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :ap_relay do
|
pipeline :ap_service_actor do
|
||||||
plug(:accepts, ["activity+json", "json"])
|
plug(:accepts, ["activity+json", "json"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -663,8 +663,17 @@ defmodule Pleroma.Web.Router do
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/relay", Pleroma.Web.ActivityPub do
|
scope "/relay", Pleroma.Web.ActivityPub do
|
||||||
pipe_through(:ap_relay)
|
pipe_through(:ap_service_actor)
|
||||||
|
|
||||||
get("/", ActivityPubController, :relay)
|
get("/", ActivityPubController, :relay)
|
||||||
|
post("/inbox", ActivityPubController, :inbox)
|
||||||
|
end
|
||||||
|
|
||||||
|
scope "/internal/fetch", Pleroma.Web.ActivityPub do
|
||||||
|
pipe_through(:ap_service_actor)
|
||||||
|
|
||||||
|
get("/", ActivityPubController, :internal_fetch)
|
||||||
|
post("/inbox", ActivityPubController, :inbox)
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", Pleroma.Web.ActivityPub do
|
scope "/", Pleroma.Web.ActivityPub do
|
||||||
|
|
|
@ -221,6 +221,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||||
user
|
user
|
||||||
|> UserEmail.password_reset_email(token_record.token)
|
|> UserEmail.password_reset_email(token_record.token)
|
||||||
|> Mailer.deliver_async()
|
|> Mailer.deliver_async()
|
||||||
|
|
||||||
|
{:ok, :enqueued}
|
||||||
else
|
else
|
||||||
false ->
|
false ->
|
||||||
{:error, "bad user identifier"}
|
{:error, "bad user identifier"}
|
||||||
|
|
|
@ -440,10 +440,10 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
|
||||||
json_response(conn, :no_content, "")
|
json_response(conn, :no_content, "")
|
||||||
else
|
else
|
||||||
{:error, "unknown user"} ->
|
{:error, "unknown user"} ->
|
||||||
put_status(conn, :not_found)
|
send_resp(conn, :not_found, "")
|
||||||
|
|
||||||
{:error, _} ->
|
{:error, _} ->
|
||||||
put_status(conn, :bad_request)
|
send_resp(conn, :bad_request, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,6 @@ defmodule Pleroma.Web.UploaderController do
|
||||||
process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)
|
process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def callbacks(conn, _) do
|
|
||||||
render_error(conn, :bad_request, "bad request")
|
|
||||||
end
|
|
||||||
|
|
||||||
defp process_callback(conn, pid, params) when is_pid(pid) do
|
defp process_callback(conn, pid, params) when is_pid(pid) do
|
||||||
send(pid, {Uploader, self(), conn, params})
|
send(pid, {Uploader, self(), conn, params})
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ defmodule Pleroma.Web.WebFinger do
|
||||||
|
|
||||||
def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do
|
def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do
|
||||||
host = Pleroma.Web.Endpoint.host()
|
host = Pleroma.Web.Endpoint.host()
|
||||||
regex = ~r/(acct:)?(?<username>\w+)@#{host}/
|
regex = ~r/(acct:)?(?<username>[a-z0-9A-Z_\.-]+)@#{host}/
|
||||||
|
|
||||||
with %{"username" => username} <- Regex.named_captures(regex, resource),
|
with %{"username" => username} <- Regex.named_captures(regex, resource),
|
||||||
%User{} = user <- User.get_cached_by_nickname(username) do
|
%User{} = user <- User.get_cached_by_nickname(username) do
|
||||||
|
|
2
mix.exs
2
mix.exs
|
@ -138,7 +138,7 @@ defmodule Pleroma.Mixfile do
|
||||||
ref: "95e8188490e97505c56636c1379ffdf036c1fdde"},
|
ref: "95e8188490e97505c56636c1379ffdf036c1fdde"},
|
||||||
{:http_signatures,
|
{:http_signatures,
|
||||||
git: "https://git.pleroma.social/pleroma/http_signatures.git",
|
git: "https://git.pleroma.social/pleroma/http_signatures.git",
|
||||||
ref: "9789401987096ead65646b52b5a2ca6bf52fc531"},
|
ref: "a2a5982fa167fb1352fbd518ce6b606ba233a989"},
|
||||||
{:pleroma_job_queue, "~> 0.2.0"},
|
{:pleroma_job_queue, "~> 0.2.0"},
|
||||||
{:telemetry, "~> 0.3"},
|
{:telemetry, "~> 0.3"},
|
||||||
{:prometheus_ex, "~> 3.0"},
|
{:prometheus_ex, "~> 3.0"},
|
||||||
|
|
2
mix.lock
2
mix.lock
|
@ -38,7 +38,7 @@
|
||||||
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
|
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
|
||||||
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
|
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"http_signatures": {:git, "https://git.pleroma.social/pleroma/http_signatures.git", "9789401987096ead65646b52b5a2ca6bf52fc531", [ref: "9789401987096ead65646b52b5a2ca6bf52fc531"]},
|
"http_signatures": {:git, "https://git.pleroma.social/pleroma/http_signatures.git", "a2a5982fa167fb1352fbd518ce6b606ba233a989", [ref: "a2a5982fa167fb1352fbd518ce6b606ba233a989"]},
|
||||||
"httpoison": {:hex, :httpoison, "1.2.0", "2702ed3da5fd7a8130fc34b11965c8cfa21ade2f232c00b42d96d4967c39a3a3", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
"httpoison": {:hex, :httpoison, "1.2.0", "2702ed3da5fd7a8130fc34b11965c8cfa21ade2f232c00b42d96d4967c39a3a3", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
|
|
|
@ -150,4 +150,34 @@ defmodule Pleroma.Object.FetcherTest do
|
||||||
assert object.id != object_two.id
|
assert object.id != object_two.id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "signed fetches" do
|
||||||
|
test_with_mock "it signs fetches when configured to do so",
|
||||||
|
Pleroma.Signature,
|
||||||
|
[:passthrough],
|
||||||
|
[] do
|
||||||
|
option = Pleroma.Config.get([:activitypub, :sign_object_fetches])
|
||||||
|
Pleroma.Config.put([:activitypub, :sign_object_fetches], true)
|
||||||
|
|
||||||
|
Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367")
|
||||||
|
|
||||||
|
assert called(Pleroma.Signature.sign(:_, :_))
|
||||||
|
|
||||||
|
Pleroma.Config.put([:activitypub, :sign_object_fetches], option)
|
||||||
|
end
|
||||||
|
|
||||||
|
test_with_mock "it doesn't sign fetches when not configured to do so",
|
||||||
|
Pleroma.Signature,
|
||||||
|
[:passthrough],
|
||||||
|
[] do
|
||||||
|
option = Pleroma.Config.get([:activitypub, :sign_object_fetches])
|
||||||
|
Pleroma.Config.put([:activitypub, :sign_object_fetches], false)
|
||||||
|
|
||||||
|
Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367")
|
||||||
|
|
||||||
|
refute called(Pleroma.Signature.sign(:_, :_))
|
||||||
|
|
||||||
|
Pleroma.Config.put([:activitypub, :sign_object_fetches], option)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,25 +31,29 @@ defmodule Pleroma.SignatureTest do
|
||||||
65_537
|
65_537
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defp make_fake_signature(key_id), do: "keyId=\"#{key_id}\""
|
||||||
|
|
||||||
|
defp make_fake_conn(key_id),
|
||||||
|
do: %Plug.Conn{req_headers: %{"signature" => make_fake_signature(key_id <> "#main-key")}}
|
||||||
|
|
||||||
describe "fetch_public_key/1" do
|
describe "fetch_public_key/1" do
|
||||||
test "it returns key" do
|
test "it returns key" do
|
||||||
expected_result = {:ok, @rsa_public_key}
|
expected_result = {:ok, @rsa_public_key}
|
||||||
|
|
||||||
user = insert(:user, %{info: %{source_data: %{"publicKey" => @public_key}}})
|
user = insert(:user, %{info: %{source_data: %{"publicKey" => @public_key}}})
|
||||||
|
|
||||||
assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => user.ap_id}}) ==
|
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == expected_result
|
||||||
expected_result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error when not found user" do
|
test "it returns error when not found user" do
|
||||||
assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => "test-ap_id"}}) ==
|
assert Signature.fetch_public_key(make_fake_conn("test-ap_id")) ==
|
||||||
{:error, :error}
|
{:error, :error}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error if public key is empty" do
|
test "it returns error if public key is empty" do
|
||||||
user = insert(:user, %{info: %{source_data: %{"publicKey" => %{}}}})
|
user = insert(:user, %{info: %{source_data: %{"publicKey" => %{}}}})
|
||||||
|
|
||||||
assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => user.ap_id}}) ==
|
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) ==
|
||||||
{:error, :error}
|
{:error, :error}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -58,12 +62,12 @@ defmodule Pleroma.SignatureTest do
|
||||||
test "it returns key" do
|
test "it returns key" do
|
||||||
ap_id = "https://mastodon.social/users/lambadalambda"
|
ap_id = "https://mastodon.social/users/lambadalambda"
|
||||||
|
|
||||||
assert Signature.refetch_public_key(%Plug.Conn{params: %{"actor" => ap_id}}) ==
|
assert Signature.refetch_public_key(make_fake_conn(ap_id)) ==
|
||||||
{:ok, @rsa_public_key}
|
{:ok, @rsa_public_key}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error when not found user" do
|
test "it returns error when not found user" do
|
||||||
assert Signature.refetch_public_key(%Plug.Conn{params: %{"actor" => "test-ap_id"}}) ==
|
assert Signature.refetch_public_key(make_fake_conn("test-ap_id")) ==
|
||||||
{:error, {:error, :ok}}
|
{:error, {:error, :ok}}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,19 +42,18 @@ defmodule Pleroma.DataCase do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_local_uploader(_context) do
|
def ensure_local_uploader(context) do
|
||||||
|
test_uploader = Map.get(context, :uploader, Pleroma.Uploaders.Local)
|
||||||
uploader = Pleroma.Config.get([Pleroma.Upload, :uploader])
|
uploader = Pleroma.Config.get([Pleroma.Upload, :uploader])
|
||||||
filters = Pleroma.Config.get([Pleroma.Upload, :filters])
|
filters = Pleroma.Config.get([Pleroma.Upload, :filters])
|
||||||
|
|
||||||
unless uploader == Pleroma.Uploaders.Local || filters != [] do
|
Pleroma.Config.put([Pleroma.Upload, :uploader], test_uploader)
|
||||||
Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
Pleroma.Config.put([Pleroma.Upload, :filters], [])
|
||||||
Pleroma.Config.put([Pleroma.Upload, :filters], [])
|
|
||||||
|
|
||||||
on_exit(fn ->
|
on_exit(fn ->
|
||||||
Pleroma.Config.put([Pleroma.Upload, :uploader], uploader)
|
Pleroma.Config.put([Pleroma.Upload, :uploader], uploader)
|
||||||
Pleroma.Config.put([Pleroma.Upload, :filters], filters)
|
Pleroma.Config.put([Pleroma.Upload, :filters], filters)
|
||||||
end)
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,9 +3,96 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.UploadTest do
|
defmodule Pleroma.UploadTest do
|
||||||
alias Pleroma.Upload
|
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
|
|
||||||
|
alias Pleroma.Upload
|
||||||
|
alias Pleroma.Uploaders.Uploader
|
||||||
|
|
||||||
|
@upload_file %Plug.Upload{
|
||||||
|
content_type: "image/jpg",
|
||||||
|
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||||
|
filename: "image.jpg"
|
||||||
|
}
|
||||||
|
|
||||||
|
defmodule TestUploaderBase do
|
||||||
|
def put_file(%{path: path} = _upload, module_name) do
|
||||||
|
task_pid =
|
||||||
|
Task.async(fn ->
|
||||||
|
:timer.sleep(10)
|
||||||
|
|
||||||
|
{Uploader, path}
|
||||||
|
|> :global.whereis_name()
|
||||||
|
|> send({Uploader, self(), {:test}, %{}})
|
||||||
|
|
||||||
|
assert_receive {Uploader, {:test}}, 4_000
|
||||||
|
end)
|
||||||
|
|
||||||
|
Agent.start(fn -> task_pid end, name: module_name)
|
||||||
|
|
||||||
|
:wait_callback
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Tried storing a file when http callback response success result" do
|
||||||
|
defmodule TestUploaderSuccess do
|
||||||
|
def http_callback(conn, _params),
|
||||||
|
do: {:ok, conn, {:file, "post-process-file.jpg"}}
|
||||||
|
|
||||||
|
def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__)
|
||||||
|
end
|
||||||
|
|
||||||
|
setup do: [uploader: TestUploaderSuccess]
|
||||||
|
setup [:ensure_local_uploader]
|
||||||
|
|
||||||
|
test "it returns file" do
|
||||||
|
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||||
|
|
||||||
|
assert Upload.store(@upload_file) ==
|
||||||
|
{:ok,
|
||||||
|
%{
|
||||||
|
"name" => "image.jpg",
|
||||||
|
"type" => "Document",
|
||||||
|
"url" => [
|
||||||
|
%{
|
||||||
|
"href" => "http://localhost:4001/media/post-process-file.jpg",
|
||||||
|
"mediaType" => "image/jpeg",
|
||||||
|
"type" => "Link"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
|
||||||
|
Task.await(Agent.get(TestUploaderSuccess, fn task_pid -> task_pid end))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Tried storing a file when http callback response error" do
|
||||||
|
defmodule TestUploaderError do
|
||||||
|
def http_callback(conn, _params), do: {:error, conn, "Errors"}
|
||||||
|
|
||||||
|
def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__)
|
||||||
|
end
|
||||||
|
|
||||||
|
setup do: [uploader: TestUploaderError]
|
||||||
|
setup [:ensure_local_uploader]
|
||||||
|
|
||||||
|
test "it returns error" do
|
||||||
|
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||||
|
assert Upload.store(@upload_file) == {:error, "Errors"}
|
||||||
|
Task.await(Agent.get(TestUploaderError, fn task_pid -> task_pid end))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Tried storing a file when http callback doesn't response by timeout" do
|
||||||
|
defmodule(TestUploader, do: def(put_file(_upload), do: :wait_callback))
|
||||||
|
setup do: [uploader: TestUploader]
|
||||||
|
setup [:ensure_local_uploader]
|
||||||
|
|
||||||
|
test "it returns error" do
|
||||||
|
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||||
|
assert Upload.store(@upload_file) == {:error, "Uploader callback timeout"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "Storing a file with the Local uploader" do
|
describe "Storing a file with the Local uploader" do
|
||||||
setup [:ensure_local_uploader]
|
setup [:ensure_local_uploader]
|
||||||
|
|
||||||
|
|
|
@ -1310,4 +1310,21 @@ defmodule Pleroma.UserTest do
|
||||||
assert following == 0
|
assert following == 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "is_internal_user?/1" do
|
||||||
|
test "non-internal user returns false" do
|
||||||
|
user = insert(:user)
|
||||||
|
refute User.is_internal_user?(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "user with no nickname returns true" do
|
||||||
|
user = insert(:user, %{nickname: nil})
|
||||||
|
assert User.is_internal_user?(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "user with internal-prefixed nickname returns true" do
|
||||||
|
user = insert(:user, %{nickname: "internal.test"})
|
||||||
|
assert User.is_internal_user?(user)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,6 +48,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "/internal/fetch" do
|
||||||
|
test "it returns the internal fetch user", %{conn: conn} do
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> get(activity_pub_path(conn, :internal_fetch))
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert res["id"] =~ "/fetch"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "/users/:nickname" do
|
describe "/users/:nickname" do
|
||||||
test "it returns a json representation of the user with accept application/json", %{
|
test "it returns a json representation of the user with accept application/json", %{
|
||||||
conn: conn
|
conn: conn
|
||||||
|
|
|
@ -3849,14 +3849,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
||||||
test "it returns 404 when user is not found", %{conn: conn, user: user} do
|
test "it returns 404 when user is not found", %{conn: conn, user: user} do
|
||||||
conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
|
conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
|
||||||
assert conn.status == 404
|
assert conn.status == 404
|
||||||
refute conn.resp_body
|
assert conn.resp_body == ""
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns 400 when user is not local", %{conn: conn, user: user} do
|
test "it returns 400 when user is not local", %{conn: conn, user: user} do
|
||||||
{:ok, user} = Repo.update(Changeset.change(user, local: false))
|
{:ok, user} = Repo.update(Changeset.change(user, local: false))
|
||||||
conn = post(conn, "/auth/password?email=#{user.email}")
|
conn = post(conn, "/auth/password?email=#{user.email}")
|
||||||
assert conn.status == 400
|
assert conn.status == 400
|
||||||
refute conn.resp_body
|
assert conn.resp_body == ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1119,14 +1119,14 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
test "it returns 404 when user is not found", %{conn: conn, user: user} do
|
test "it returns 404 when user is not found", %{conn: conn, user: user} do
|
||||||
conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
|
conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
|
||||||
assert conn.status == 404
|
assert conn.status == 404
|
||||||
refute conn.resp_body
|
assert conn.resp_body == ""
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns 400 when user is not local", %{conn: conn, user: user} do
|
test "it returns 400 when user is not local", %{conn: conn, user: user} do
|
||||||
{:ok, user} = Repo.update(Changeset.change(user, local: false))
|
{:ok, user} = Repo.update(Changeset.change(user, local: false))
|
||||||
conn = post(conn, "/api/account/password_reset?email=#{user.email}")
|
conn = post(conn, "/api/account/password_reset?email=#{user.email}")
|
||||||
assert conn.status == 400
|
assert conn.status == 400
|
||||||
refute conn.resp_body
|
assert conn.resp_body == ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.UploaderControllerTest do
|
||||||
|
use Pleroma.Web.ConnCase
|
||||||
|
alias Pleroma.Uploaders.Uploader
|
||||||
|
|
||||||
|
describe "callback/2" do
|
||||||
|
test "it returns 400 response when process callback isn't alive", %{conn: conn} do
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> post(uploader_path(conn, :callback, "test-path"))
|
||||||
|
|
||||||
|
assert res.status == 400
|
||||||
|
assert res.resp_body == "{\"error\":\"bad request\"}"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns success result", %{conn: conn} do
|
||||||
|
task =
|
||||||
|
Task.async(fn ->
|
||||||
|
receive do
|
||||||
|
{Uploader, pid, conn, _params} ->
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_status(:ok)
|
||||||
|
|> Phoenix.Controller.json(%{upload_path: "test-path"})
|
||||||
|
|
||||||
|
send(pid, {Uploader, conn})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
:global.register_name({Uploader, "test-path"}, task.pid)
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> post(uploader_path(conn, :callback, "test-path"))
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert res == %{"upload_path" => "test-path"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Reference in New Issue