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.
|
||||
- Addressable lists
|
||||
- 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
|
||||
- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
|
||||
|
|
|
@ -305,7 +305,8 @@ config :pleroma, :activitypub,
|
|||
accept_blocks: true,
|
||||
unfollow_blocked: true,
|
||||
outgoing_blocks: true,
|
||||
follow_handshake_timeout: 500
|
||||
follow_handshake_timeout: 500,
|
||||
sign_object_fetches: true
|
||||
|
||||
config :pleroma, :user, deny_follow_blocked: true
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ config :pleroma, :instance,
|
|||
skip_thread_containment: false,
|
||||
federating: false
|
||||
|
||||
config :pleroma, :activitypub, sign_object_fetches: false
|
||||
|
||||
# Configure your database
|
||||
config :pleroma, Pleroma.Repo,
|
||||
adapter: Ecto.Adapters.Postgres,
|
||||
|
|
|
@ -31,6 +31,7 @@ Feel free to contact us to be added to this list!
|
|||
- Features: No Streaming
|
||||
|
||||
### Fedilab
|
||||
- Homepage: <https://fedilab.app/>
|
||||
- Source Code: <https://gitlab.com/tom79/mastalab/>
|
||||
- Contact: [@tom79@mastodon.social](https://mastodon.social/users/tom79)
|
||||
- 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
|
||||
* ``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
|
||||
* ``sign_object_fetches``: Sign object fetches with HTTP signatures
|
||||
|
||||
## :http_security
|
||||
* ``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,
|
||||
enabled: true,
|
||||
redirect_on_failure: true
|
||||
proxy_opts: [
|
||||
redirect_on_failure: true
|
||||
]
|
||||
#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.
|
||||
|
|
|
@ -242,6 +242,14 @@ So for example, if the task is `mix pleroma.user set admin --admin`, you should
|
|||
```sh
|
||||
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
|
||||
Generally, doing the following is enough:
|
||||
```sh
|
||||
|
|
|
@ -140,6 +140,11 @@ defmodule Pleroma.Application do
|
|||
id: :federator_init,
|
||||
start: {Task, :start_link, [&Pleroma.Web.Federator.init/0]},
|
||||
restart: :temporary
|
||||
},
|
||||
%{
|
||||
id: :internal_fetch_init,
|
||||
start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]},
|
||||
restart: :temporary
|
||||
}
|
||||
] ++
|
||||
streamer_child() ++
|
||||
|
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Object.Fetcher do
|
|||
alias Pleroma.HTTP
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Containment
|
||||
alias Pleroma.Signature
|
||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.OStatus
|
||||
|
||||
|
@ -82,15 +84,52 @@ defmodule Pleroma.Object.Fetcher do
|
|||
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
|
||||
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"),
|
||||
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
||||
HTTP.get(
|
||||
id,
|
||||
[{:Accept, "application/activity+json"}]
|
||||
),
|
||||
{:ok, %{body: body, status: code}} when code in 200..299 <- HTTP.get(id, headers),
|
||||
{:ok, data} <- Jason.decode(body),
|
||||
:ok <- Containment.contain_origin_from_id(id, data) do
|
||||
{:ok, data}
|
||||
|
|
|
@ -8,10 +8,16 @@ defmodule Pleroma.Signature do
|
|||
alias Pleroma.Keys
|
||||
alias Pleroma.User
|
||||
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
|
||||
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}
|
||||
else
|
||||
|
@ -21,7 +27,8 @@ defmodule Pleroma.Signature do
|
|||
end
|
||||
|
||||
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, public_key} <- User.get_public_key_for_ap_id(actor_id) do
|
||||
{:ok, public_key}
|
||||
|
|
|
@ -68,7 +68,14 @@ defmodule Pleroma.Uploaders.Uploader do
|
|||
{:error, error}
|
||||
end
|
||||
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
|
||||
|
|
|
@ -1157,19 +1157,18 @@ defmodule Pleroma.User do
|
|||
end
|
||||
end
|
||||
|
||||
def get_or_create_instance_user do
|
||||
relay_uri = "#{Pleroma.Web.Endpoint.url()}/relay"
|
||||
|
||||
if user = get_cached_by_ap_id(relay_uri) do
|
||||
@doc "Creates an internal service actor by URI if missing. Optionally takes nickname for addressing."
|
||||
def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do
|
||||
if user = get_cached_by_ap_id(uri) do
|
||||
user
|
||||
else
|
||||
changes =
|
||||
%User{info: %User.Info{}}
|
||||
|> cast(%{}, [:ap_id, :nickname, :local])
|
||||
|> put_change(:ap_id, relay_uri)
|
||||
|> put_change(:nickname, nil)
|
||||
|> put_change(:ap_id, uri)
|
||||
|> put_change(:nickname, nickname)
|
||||
|> put_change(:local, true)
|
||||
|> put_change(:follower_address, relay_uri <> "/followers")
|
||||
|> put_change(:follower_address, uri <> "/followers")
|
||||
|
||||
{:ok, user} = Repo.insert(changes)
|
||||
user
|
||||
|
@ -1411,4 +1410,8 @@ defmodule Pleroma.User do
|
|||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
alias Pleroma.Object.Fetcher
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||
alias Pleroma.Web.ActivityPub.ObjectView
|
||||
alias Pleroma.Web.ActivityPub.Relay
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
@ -206,9 +207,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
json(conn, dgettext("errors", "error"))
|
||||
end
|
||||
|
||||
def relay(conn, _params) do
|
||||
with %User{} = user <- Relay.get_actor(),
|
||||
{:ok, user} <- User.ensure_keys_present(user) do
|
||||
defp represent_service_actor(%User{} = user, conn) do
|
||||
with {:ok, user} <- User.ensure_keys_present(user) do
|
||||
conn
|
||||
|> put_resp_header("content-type", "application/activity+json")
|
||||
|> json(UserView.render("user.json", %{user: user}))
|
||||
|
@ -217,6 +217,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
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
|
||||
conn
|
||||
|> 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
|
||||
|
||||
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
|
||||
|
||||
def follow(target_instance) do
|
||||
|
|
|
@ -31,8 +31,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
|||
|
||||
def render("endpoints.json", _), do: %{}
|
||||
|
||||
# the instance itself is not a Person, but instead an Application
|
||||
def render("user.json", %{user: %{nickname: nil} = user}) do
|
||||
def render("service.json", %{user: user}) do
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
|
||||
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",
|
||||
"inbox" => "#{user.ap_id}/inbox",
|
||||
"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,
|
||||
"manuallyApprovesFollowers" => false,
|
||||
"publicKey" => %{
|
||||
|
@ -60,6 +60,13 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
|||
|> Map.merge(Utils.make_json_ld_header())
|
||||
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
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
{:ok, _, public_key} = Keys.keys_from_pem(user.info.keys)
|
||||
|
|
|
@ -1826,10 +1826,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
|||
|> json("")
|
||||
else
|
||||
{:error, "unknown user"} ->
|
||||
put_status(conn, :not_found)
|
||||
send_resp(conn, :not_found, "")
|
||||
|
||||
{:error, _} ->
|
||||
put_status(conn, :bad_request)
|
||||
send_resp(conn, :bad_request, "")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -586,7 +586,7 @@ defmodule Pleroma.Web.Router do
|
|||
end
|
||||
end
|
||||
|
||||
pipeline :ap_relay do
|
||||
pipeline :ap_service_actor do
|
||||
plug(:accepts, ["activity+json", "json"])
|
||||
end
|
||||
|
||||
|
@ -663,8 +663,17 @@ defmodule Pleroma.Web.Router do
|
|||
end
|
||||
|
||||
scope "/relay", Pleroma.Web.ActivityPub do
|
||||
pipe_through(:ap_relay)
|
||||
pipe_through(:ap_service_actor)
|
||||
|
||||
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
|
||||
|
||||
scope "/", Pleroma.Web.ActivityPub do
|
||||
|
|
|
@ -221,6 +221,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
|||
user
|
||||
|> UserEmail.password_reset_email(token_record.token)
|
||||
|> Mailer.deliver_async()
|
||||
|
||||
{:ok, :enqueued}
|
||||
else
|
||||
false ->
|
||||
{:error, "bad user identifier"}
|
||||
|
|
|
@ -440,10 +440,10 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
|
|||
json_response(conn, :no_content, "")
|
||||
else
|
||||
{:error, "unknown user"} ->
|
||||
put_status(conn, :not_found)
|
||||
send_resp(conn, :not_found, "")
|
||||
|
||||
{:error, _} ->
|
||||
put_status(conn, :bad_request)
|
||||
send_resp(conn, :bad_request, "")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -11,10 +11,6 @@ defmodule Pleroma.Web.UploaderController do
|
|||
process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)
|
||||
end
|
||||
|
||||
def callbacks(conn, _) do
|
||||
render_error(conn, :bad_request, "bad request")
|
||||
end
|
||||
|
||||
defp process_callback(conn, pid, params) when is_pid(pid) do
|
||||
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
|
||||
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),
|
||||
%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"},
|
||||
{:http_signatures,
|
||||
git: "https://git.pleroma.social/pleroma/http_signatures.git",
|
||||
ref: "9789401987096ead65646b52b5a2ca6bf52fc531"},
|
||||
ref: "a2a5982fa167fb1352fbd518ce6b606ba233a989"},
|
||||
{:pleroma_job_queue, "~> 0.2.0"},
|
||||
{:telemetry, "~> 0.3"},
|
||||
{: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"},
|
||||
"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"},
|
||||
"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"},
|
||||
"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"},
|
||||
|
|
|
@ -150,4 +150,34 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
assert object.id != object_two.id
|
||||
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
|
||||
|
|
|
@ -31,25 +31,29 @@ defmodule Pleroma.SignatureTest do
|
|||
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
|
||||
test "it returns key" do
|
||||
expected_result = {:ok, @rsa_public_key}
|
||||
|
||||
user = insert(:user, %{info: %{source_data: %{"publicKey" => @public_key}}})
|
||||
|
||||
assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => user.ap_id}}) ==
|
||||
expected_result
|
||||
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == expected_result
|
||||
end
|
||||
|
||||
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}
|
||||
end
|
||||
|
||||
test "it returns error if public key is empty" do
|
||||
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}
|
||||
end
|
||||
end
|
||||
|
@ -58,12 +62,12 @@ defmodule Pleroma.SignatureTest do
|
|||
test "it returns key" do
|
||||
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}
|
||||
end
|
||||
|
||||
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}}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,19 +42,18 @@ defmodule Pleroma.DataCase do
|
|||
:ok
|
||||
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])
|
||||
filters = Pleroma.Config.get([Pleroma.Upload, :filters])
|
||||
|
||||
unless uploader == Pleroma.Uploaders.Local || filters != [] do
|
||||
Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
||||
Pleroma.Config.put([Pleroma.Upload, :filters], [])
|
||||
Pleroma.Config.put([Pleroma.Upload, :uploader], test_uploader)
|
||||
Pleroma.Config.put([Pleroma.Upload, :filters], [])
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put([Pleroma.Upload, :uploader], uploader)
|
||||
Pleroma.Config.put([Pleroma.Upload, :filters], filters)
|
||||
end)
|
||||
end
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put([Pleroma.Upload, :uploader], uploader)
|
||||
Pleroma.Config.put([Pleroma.Upload, :filters], filters)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
|
|
@ -3,9 +3,96 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.UploadTest do
|
||||
alias Pleroma.Upload
|
||||
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
|
||||
setup [:ensure_local_uploader]
|
||||
|
||||
|
|
|
@ -1310,4 +1310,21 @@ defmodule Pleroma.UserTest do
|
|||
assert following == 0
|
||||
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
|
||||
|
|
|
@ -48,6 +48,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
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
|
||||
test "it returns a json representation of the user with accept application/json", %{
|
||||
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
|
||||
conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
|
||||
assert conn.status == 404
|
||||
refute conn.resp_body
|
||||
assert conn.resp_body == ""
|
||||
end
|
||||
|
||||
test "it returns 400 when user is not local", %{conn: conn, user: user} do
|
||||
{:ok, user} = Repo.update(Changeset.change(user, local: false))
|
||||
conn = post(conn, "/auth/password?email=#{user.email}")
|
||||
assert conn.status == 400
|
||||
refute conn.resp_body
|
||||
assert conn.resp_body == ""
|
||||
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
|
||||
conn = post(conn, "/api/account/password_reset?email=nonexisting_#{user.email}")
|
||||
assert conn.status == 404
|
||||
refute conn.resp_body
|
||||
assert conn.resp_body == ""
|
||||
end
|
||||
|
||||
test "it returns 400 when user is not local", %{conn: conn, user: user} do
|
||||
{:ok, user} = Repo.update(Changeset.change(user, local: false))
|
||||
conn = post(conn, "/api/account/password_reset?email=#{user.email}")
|
||||
assert conn.status == 400
|
||||
refute conn.resp_body
|
||||
assert conn.resp_body == ""
|
||||
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