forked from AkkomaGang/akkoma
Merge develop to refactor/mix-tasks
This commit is contained in:
commit
9938fa3293
86 changed files with 1850 additions and 1406 deletions
|
@ -72,6 +72,7 @@
|
||||||
config :pleroma, :websub, Pleroma.Web.Websub
|
config :pleroma, :websub, Pleroma.Web.Websub
|
||||||
config :pleroma, :ostatus, Pleroma.Web.OStatus
|
config :pleroma, :ostatus, Pleroma.Web.OStatus
|
||||||
config :pleroma, :httpoison, Pleroma.HTTP
|
config :pleroma, :httpoison, Pleroma.HTTP
|
||||||
|
config :tesla, adapter: Tesla.Adapter.Hackney
|
||||||
|
|
||||||
# Configures http settings, upstream proxy etc.
|
# Configures http settings, upstream proxy etc.
|
||||||
config :pleroma, :http, proxy_url: nil
|
config :pleroma, :http, proxy_url: nil
|
||||||
|
|
|
@ -49,10 +49,9 @@
|
||||||
hostname: "localhost",
|
hostname: "localhost",
|
||||||
pool_size: 10
|
pool_size: 10
|
||||||
|
|
||||||
try do
|
if File.exists?("./config/dev.secret.exs") do
|
||||||
import_config "dev.secret.exs"
|
import_config "dev.secret.exs"
|
||||||
rescue
|
else
|
||||||
_ ->
|
|
||||||
IO.puts(
|
IO.puts(
|
||||||
"!!! RUNNING IN LOCALHOST DEV MODE! !!!\nFEDERATION WON'T WORK UNTIL YOU CONFIGURE A dev.secret.exs"
|
"!!! RUNNING IN LOCALHOST DEV MODE! !!!\nFEDERATION WON'T WORK UNTIL YOU CONFIGURE A dev.secret.exs"
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
config :pleroma, :websub, Pleroma.Web.WebsubMock
|
config :pleroma, :websub, Pleroma.Web.WebsubMock
|
||||||
config :pleroma, :ostatus, Pleroma.Web.OStatusMock
|
config :pleroma, :ostatus, Pleroma.Web.OStatusMock
|
||||||
config :pleroma, :httpoison, HTTPoisonMock
|
config :tesla, adapter: Tesla.Mock
|
||||||
|
|
||||||
try do
|
try do
|
||||||
import_config "test.secret.exs"
|
import_config "test.secret.exs"
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
CREATE USER <%= dbuser %> WITH ENCRYPTED PASSWORD '<%= dbpass %>' CREATEDB;
|
CREATE USER pleroma WITH ENCRYPTED PASSWORD '<%= dbpass %>';
|
||||||
-- in case someone runs this second time accidentally
|
CREATE DATABASE pleroma_dev OWNER pleroma;
|
||||||
ALTER USER <%= dbuser %> WITH ENCRYPTED PASSWORD '<%= dbpass %>' CREATEDB;
|
\c pleroma_dev;
|
||||||
CREATE DATABASE <%= dbname %>;
|
|
||||||
ALTER DATABASE <%= dbname %> OWNER TO <%= dbuser %>;
|
|
||||||
\c <%= dbname %>;
|
|
||||||
--Extensions made by ecto.migrate that need superuser access
|
--Extensions made by ecto.migrate that need superuser access
|
||||||
CREATE EXTENSION IF NOT EXISTS citext;
|
CREATE EXTENSION IF NOT EXISTS citext;
|
||||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||||
|
|
|
@ -116,8 +116,8 @@ def add_user_links({subs, text}, mentions) do
|
||||||
subs ++
|
subs ++
|
||||||
Enum.map(mentions, fn {match, %User{ap_id: ap_id, info: info}, uuid} ->
|
Enum.map(mentions, fn {match, %User{ap_id: ap_id, info: info}, uuid} ->
|
||||||
ap_id =
|
ap_id =
|
||||||
if is_binary(info["source_data"]["url"]) do
|
if is_binary(info.source_data["url"]) do
|
||||||
info["source_data"]["url"]
|
info.source_data["url"]
|
||||||
else
|
else
|
||||||
ap_id
|
ap_id
|
||||||
end
|
end
|
||||||
|
|
27
lib/pleroma/http/connection.ex
Normal file
27
lib/pleroma/http/connection.ex
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
defmodule Pleroma.HTTP.Connection do
|
||||||
|
@moduledoc """
|
||||||
|
Connection for http-requests.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@hackney_options [pool: :default]
|
||||||
|
@adapter Application.get_env(:tesla, :adapter)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Configure a client connection
|
||||||
|
|
||||||
|
# Returns
|
||||||
|
|
||||||
|
Tesla.Env.client
|
||||||
|
"""
|
||||||
|
@spec new(Keyword.t()) :: Tesla.Env.client()
|
||||||
|
def new(opts \\ []) do
|
||||||
|
Tesla.client([], {@adapter, hackney_options(opts)})
|
||||||
|
end
|
||||||
|
|
||||||
|
# fetch Hackney options
|
||||||
|
#
|
||||||
|
defp hackney_options(opts \\ []) do
|
||||||
|
options = Keyword.get(opts, :adapter, [])
|
||||||
|
@hackney_options ++ options
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,14 +1,42 @@
|
||||||
defmodule Pleroma.HTTP do
|
defmodule Pleroma.HTTP do
|
||||||
require HTTPoison
|
@moduledoc """
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
alias Pleroma.HTTP.Connection
|
||||||
|
alias Pleroma.HTTP.RequestBuilder, as: Builder
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Builds and perform http request.
|
||||||
|
|
||||||
|
# Arguments:
|
||||||
|
`method` - :get, :post, :put, :delete
|
||||||
|
`url`
|
||||||
|
`body`
|
||||||
|
`headers` - a keyworld list of headers, e.g. `[{"content-type", "text/plain"}]`
|
||||||
|
`options` - custom, per-request middleware or adapter options
|
||||||
|
|
||||||
|
# Returns:
|
||||||
|
`{:ok, %Tesla.Env{}}` or `{:error, error}`
|
||||||
|
|
||||||
|
"""
|
||||||
def request(method, url, body \\ "", headers \\ [], options \\ []) do
|
def request(method, url, body \\ "", headers \\ [], options \\ []) do
|
||||||
options =
|
options =
|
||||||
process_request_options(options)
|
process_request_options(options)
|
||||||
|> process_sni_options(url)
|
|> process_sni_options(url)
|
||||||
|
|
||||||
HTTPoison.request(method, url, body, headers, options)
|
%{}
|
||||||
|
|> Builder.method(method)
|
||||||
|
|> Builder.headers(headers)
|
||||||
|
|> Builder.opts(options)
|
||||||
|
|> Builder.url(url)
|
||||||
|
|> Builder.add_param(:body, :body, body)
|
||||||
|
|> Enum.into([])
|
||||||
|
|> (&Tesla.request(Connection.new(), &1)).()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp process_sni_options(options, nil), do: options
|
||||||
|
|
||||||
defp process_sni_options(options, url) do
|
defp process_sni_options(options, url) do
|
||||||
uri = URI.parse(url)
|
uri = URI.parse(url)
|
||||||
host = uri.host |> to_charlist()
|
host = uri.host |> to_charlist()
|
||||||
|
@ -22,7 +50,7 @@ defp process_sni_options(options, url) do
|
||||||
def process_request_options(options) do
|
def process_request_options(options) do
|
||||||
config = Application.get_env(:pleroma, :http, [])
|
config = Application.get_env(:pleroma, :http, [])
|
||||||
proxy = Keyword.get(config, :proxy_url, nil)
|
proxy = Keyword.get(config, :proxy_url, nil)
|
||||||
options = options ++ [hackney: [pool: :default]]
|
options = options ++ [adapter: [pool: :default]]
|
||||||
|
|
||||||
case proxy do
|
case proxy do
|
||||||
nil -> options
|
nil -> options
|
||||||
|
@ -30,8 +58,19 @@ def process_request_options(options) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(url, headers \\ [], options \\ []), do: request(:get, url, "", headers, options)
|
@doc """
|
||||||
|
Performs GET request.
|
||||||
|
|
||||||
|
See `Pleroma.HTTP.request/5`
|
||||||
|
"""
|
||||||
|
def get(url, headers \\ [], options \\ []),
|
||||||
|
do: request(:get, url, "", headers, options)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Performs POST request.
|
||||||
|
|
||||||
|
See `Pleroma.HTTP.request/5`
|
||||||
|
"""
|
||||||
def post(url, body, headers \\ [], options \\ []),
|
def post(url, body, headers \\ [], options \\ []),
|
||||||
do: request(:post, url, body, headers, options)
|
do: request(:post, url, body, headers, options)
|
||||||
end
|
end
|
||||||
|
|
126
lib/pleroma/http/request_builder.ex
Normal file
126
lib/pleroma/http/request_builder.ex
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
defmodule Pleroma.HTTP.RequestBuilder do
|
||||||
|
@moduledoc """
|
||||||
|
Helper functions for building Tesla requests
|
||||||
|
"""
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Specify the request method when building a request
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
- request (Map) - Collected request options
|
||||||
|
- m (atom) - Request method
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
Map
|
||||||
|
"""
|
||||||
|
@spec method(map(), atom) :: map()
|
||||||
|
def method(request, m) do
|
||||||
|
Map.put_new(request, :method, m)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Specify the request method when building a request
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
- request (Map) - Collected request options
|
||||||
|
- u (String) - Request URL
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
Map
|
||||||
|
"""
|
||||||
|
@spec url(map(), String.t()) :: map()
|
||||||
|
def url(request, u) do
|
||||||
|
Map.put_new(request, :url, u)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Add headers to the request
|
||||||
|
"""
|
||||||
|
@spec headers(map(), list(tuple)) :: map()
|
||||||
|
def headers(request, h) do
|
||||||
|
Map.put_new(request, :headers, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Add custom, per-request middleware or adapter options to the request
|
||||||
|
"""
|
||||||
|
@spec opts(map(), Keyword.t()) :: map()
|
||||||
|
def opts(request, options) do
|
||||||
|
Map.put_new(request, :opts, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Add optional parameters to the request
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
- request (Map) - Collected request options
|
||||||
|
- definitions (Map) - Map of parameter name to parameter location.
|
||||||
|
- options (KeywordList) - The provided optional parameters
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
Map
|
||||||
|
"""
|
||||||
|
@spec add_optional_params(map(), %{optional(atom) => atom}, keyword()) :: map()
|
||||||
|
def add_optional_params(request, _, []), do: request
|
||||||
|
|
||||||
|
def add_optional_params(request, definitions, [{key, value} | tail]) do
|
||||||
|
case definitions do
|
||||||
|
%{^key => location} ->
|
||||||
|
request
|
||||||
|
|> add_param(location, key, value)
|
||||||
|
|> add_optional_params(definitions, tail)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
add_optional_params(request, definitions, tail)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Add optional parameters to the request
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
- request (Map) - Collected request options
|
||||||
|
- location (atom) - Where to put the parameter
|
||||||
|
- key (atom) - The name of the parameter
|
||||||
|
- value (any) - The value of the parameter
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
|
||||||
|
Map
|
||||||
|
"""
|
||||||
|
@spec add_param(map(), atom, atom, any()) :: map()
|
||||||
|
def add_param(request, :body, :body, value), do: Map.put(request, :body, value)
|
||||||
|
|
||||||
|
def add_param(request, :body, key, value) do
|
||||||
|
request
|
||||||
|
|> Map.put_new_lazy(:body, &Tesla.Multipart.new/0)
|
||||||
|
|> Map.update!(
|
||||||
|
:body,
|
||||||
|
&Tesla.Multipart.add_field(&1, key, Poison.encode!(value),
|
||||||
|
headers: [{:"Content-Type", "application/json"}]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_param(request, :file, name, path) do
|
||||||
|
request
|
||||||
|
|> Map.put_new_lazy(:body, &Tesla.Multipart.new/0)
|
||||||
|
|> Map.update!(:body, &Tesla.Multipart.add_file(&1, path, name: name))
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_param(request, :form, name, value) do
|
||||||
|
request
|
||||||
|
|> Map.update(:body, %{name => value}, &Map.put(&1, name, value))
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_param(request, location, key, value) do
|
||||||
|
Map.update(request, location, [{key, value}], &(&1 ++ [{key, value}]))
|
||||||
|
end
|
||||||
|
end
|
|
@ -20,7 +20,7 @@ def call(conn, _) do
|
||||||
with token when not is_nil(token) <- token,
|
with token when not is_nil(token) <- token,
|
||||||
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
|
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
|
||||||
%User{} = user <- Repo.get(User, user_id),
|
%User{} = user <- Repo.get(User, user_id),
|
||||||
false <- !!user.info["deactivated"] do
|
false <- !!user.info.deactivated do
|
||||||
conn
|
conn
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
else
|
else
|
||||||
|
|
|
@ -6,7 +6,7 @@ def init(options) do
|
||||||
options
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(%{assigns: %{user: %User{info: %{"deactivated" => true}}}} = conn, _) do
|
def call(%{assigns: %{user: %User{info: %{deactivated: true}}}} = conn, _) do
|
||||||
conn
|
conn
|
||||||
|> assign(:user, nil)
|
|> assign(:user, nil)
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ def init(options) do
|
||||||
options
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(%{assigns: %{user: %User{info: %{"is_admin" => true}}}} = conn, _) do
|
def call(%{assigns: %{user: %User{info: %{is_admin: true}}}} = conn, _) do
|
||||||
conn
|
conn
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ def put_file(upload) do
|
||||||
extension = String.split(upload.name, ".") |> List.last()
|
extension = String.split(upload.name, ".") |> List.last()
|
||||||
query = "#{cgi}?#{extension}"
|
query = "#{cgi}?#{extension}"
|
||||||
|
|
||||||
with {:ok, %{status_code: 200, body: body}} <- @httpoison.post(query, file_data) do
|
with {:ok, %{status: 200, body: body}} <- @httpoison.post(query, file_data) do
|
||||||
remote_file_name = String.split(body) |> List.first()
|
remote_file_name = String.split(body) |> List.first()
|
||||||
public_url = "#{files}/#{remote_file_name}.#{extension}"
|
public_url = "#{files}/#{remote_file_name}.#{extension}"
|
||||||
{:ok, {:url, public_url}}
|
{:ok, {:url, public_url}}
|
||||||
|
|
|
@ -25,10 +25,10 @@ def get_token() do
|
||||||
["Content-Type": "application/json"],
|
["Content-Type": "application/json"],
|
||||||
hackney: [:insecure]
|
hackney: [:insecure]
|
||||||
) do
|
) do
|
||||||
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
|
{:ok, %Tesla.Env{status: 200, body: body}} ->
|
||||||
body["access"]["token"]["id"]
|
body["access"]["token"]["id"]
|
||||||
|
|
||||||
{:ok, %HTTPoison.Response{status_code: _}} ->
|
{:ok, %Tesla.Env{status: _}} ->
|
||||||
""
|
""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,10 +13,10 @@ def upload_file(filename, body, content_type) do
|
||||||
token = Pleroma.Uploaders.Swift.Keystone.get_token()
|
token = Pleroma.Uploaders.Swift.Keystone.get_token()
|
||||||
|
|
||||||
case put("#{filename}", body, "X-Auth-Token": token, "Content-Type": content_type) do
|
case put("#{filename}", body, "X-Auth-Token": token, "Content-Type": content_type) do
|
||||||
{:ok, %HTTPoison.Response{status_code: 201}} ->
|
{:ok, %Tesla.Env{status: 201}} ->
|
||||||
{:ok, {:file, filename}}
|
{:ok, {:file, filename}}
|
||||||
|
|
||||||
{:ok, %HTTPoison.Response{status_code: 401}} ->
|
{:ok, %Tesla.Env{status: 401}} ->
|
||||||
{:error, "Unauthorized, Bad Token"}
|
{:error, "Unauthorized, Bad Token"}
|
||||||
|
|
||||||
{:error, _} ->
|
{:error, _} ->
|
||||||
|
|
|
@ -4,6 +4,8 @@ defmodule Pleroma.User do
|
||||||
import Ecto.{Changeset, Query}
|
import Ecto.{Changeset, Query}
|
||||||
alias Pleroma.{Repo, User, Object, Web, Activity, Notification}
|
alias Pleroma.{Repo, User, Object, Web, Activity, Notification}
|
||||||
alias Comeonin.Pbkdf2
|
alias Comeonin.Pbkdf2
|
||||||
|
alias Pleroma.Formatter
|
||||||
|
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
|
||||||
alias Pleroma.Web.{OStatus, Websub, OAuth}
|
alias Pleroma.Web.{OStatus, Websub, OAuth}
|
||||||
alias Pleroma.Web.ActivityPub.{Utils, ActivityPub}
|
alias Pleroma.Web.ActivityPub.{Utils, ActivityPub}
|
||||||
|
|
||||||
|
@ -19,11 +21,11 @@ defmodule Pleroma.User do
|
||||||
field(:ap_id, :string)
|
field(:ap_id, :string)
|
||||||
field(:avatar, :map)
|
field(:avatar, :map)
|
||||||
field(:local, :boolean, default: true)
|
field(:local, :boolean, default: true)
|
||||||
field(:info, :map, default: %{})
|
|
||||||
field(:follower_address, :string)
|
field(:follower_address, :string)
|
||||||
field(:search_distance, :float, virtual: true)
|
field(:search_distance, :float, virtual: true)
|
||||||
field(:last_refreshed_at, :naive_datetime)
|
field(:last_refreshed_at, :naive_datetime)
|
||||||
has_many(:notifications, Notification)
|
has_many(:notifications, Notification)
|
||||||
|
embeds_one(:info, Pleroma.User.Info)
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
@ -36,13 +38,13 @@ def avatar_url(user) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def banner_url(user) do
|
def banner_url(user) do
|
||||||
case user.info["banner"] do
|
case user.info.banner do
|
||||||
%{"url" => [%{"href" => href} | _]} -> href
|
%{"url" => [%{"href" => href} | _]} -> href
|
||||||
_ -> "#{Web.base_url()}/images/banner.png"
|
_ -> "#{Web.base_url()}/images/banner.png"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def profile_url(%User{info: %{"source_data" => %{"url" => url}}}), do: url
|
def profile_url(%User{info: %{source_data: %{"url" => url}}}), do: url
|
||||||
def profile_url(%User{ap_id: ap_id}), do: ap_id
|
def profile_url(%User{ap_id: ap_id}), do: ap_id
|
||||||
def profile_url(_), do: nil
|
def profile_url(_), do: nil
|
||||||
|
|
||||||
|
@ -61,9 +63,7 @@ def follow_changeset(struct, params \\ %{}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def info_changeset(struct, params \\ %{}) do
|
def info_changeset(struct, params \\ %{}) do
|
||||||
struct
|
raise "NOT VALID ANYMORE"
|
||||||
|> cast(params, [:info])
|
|
||||||
|> validate_required([:info])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_info(%User{} = user) do
|
def user_info(%User{} = user) do
|
||||||
|
@ -71,27 +71,34 @@ def user_info(%User{} = user) do
|
||||||
|
|
||||||
%{
|
%{
|
||||||
following_count: length(user.following) - oneself,
|
following_count: length(user.following) - oneself,
|
||||||
note_count: user.info["note_count"] || 0,
|
note_count: user.info.note_count,
|
||||||
follower_count: user.info["follower_count"] || 0,
|
follower_count: user.info.follower_count,
|
||||||
locked: user.info["locked"] || false,
|
locked: user.info.locked,
|
||||||
default_scope: user.info["default_scope"] || "public"
|
default_scope: user.info.default_scope
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
|
@email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
|
||||||
def remote_user_creation(params) do
|
def remote_user_creation(params) do
|
||||||
|
params =
|
||||||
|
params
|
||||||
|
|> Map.put(:info, params[:info] || %{})
|
||||||
|
|
||||||
|
info_cng = User.Info.remote_user_creation(%User.Info{}, params[:info])
|
||||||
|
|
||||||
changes =
|
changes =
|
||||||
%User{}
|
%User{}
|
||||||
|> cast(params, [:bio, :name, :ap_id, :nickname, :info, :avatar])
|
|> cast(params, [:bio, :name, :ap_id, :nickname, :avatar])
|
||||||
|> validate_required([:name, :ap_id])
|
|> validate_required([:name, :ap_id])
|
||||||
|> unique_constraint(:nickname)
|
|> unique_constraint(:nickname)
|
||||||
|> validate_format(:nickname, @email_regex)
|
|> validate_format(:nickname, @email_regex)
|
||||||
|> validate_length(:bio, max: 5000)
|
|> validate_length(:bio, max: 5000)
|
||||||
|> validate_length(:name, max: 100)
|
|> validate_length(:name, max: 100)
|
||||||
|> put_change(:local, false)
|
|> put_change(:local, false)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
if changes.valid? do
|
if changes.valid? do
|
||||||
case changes.changes[:info]["source_data"] do
|
case info_cng.changes[:source_data] do
|
||||||
%{"followers" => followers} ->
|
%{"followers" => followers} ->
|
||||||
changes
|
changes
|
||||||
|> put_change(:follower_address, followers)
|
|> put_change(:follower_address, followers)
|
||||||
|
@ -109,7 +116,7 @@ def remote_user_creation(params) do
|
||||||
|
|
||||||
def update_changeset(struct, params \\ %{}) do
|
def update_changeset(struct, params \\ %{}) do
|
||||||
struct
|
struct
|
||||||
|> cast(params, [:bio, :name])
|
|> cast(params, [:bio, :name, :avatar])
|
||||||
|> unique_constraint(:nickname)
|
|> unique_constraint(:nickname)
|
||||||
|> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
|
|> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
|
||||||
|> validate_length(:bio, max: 5000)
|
|> validate_length(:bio, max: 5000)
|
||||||
|
@ -121,12 +128,17 @@ def upgrade_changeset(struct, params \\ %{}) do
|
||||||
params
|
params
|
||||||
|> Map.put(:last_refreshed_at, NaiveDateTime.utc_now())
|
|> Map.put(:last_refreshed_at, NaiveDateTime.utc_now())
|
||||||
|
|
||||||
|
info_cng =
|
||||||
|
struct.info
|
||||||
|
|> User.Info.user_upgrade(params[:info])
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|> cast(params, [:bio, :name, :info, :follower_address, :avatar, :last_refreshed_at])
|
|> cast(params, [:bio, :name, :follower_address, :avatar, :last_refreshed_at])
|
||||||
|> unique_constraint(:nickname)
|
|> unique_constraint(:nickname)
|
||||||
|> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
|
|> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
|
||||||
|> validate_length(:bio, max: 5000)
|
|> validate_length(:bio, max: 5000)
|
||||||
|> validate_length(:name, max: 100)
|
|> validate_length(:name, max: 100)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def password_update_changeset(struct, params) do
|
def password_update_changeset(struct, params) do
|
||||||
|
@ -165,6 +177,7 @@ def register_changeset(struct, params \\ %{}) do
|
||||||
|> validate_format(:email, @email_regex)
|
|> validate_format(:email, @email_regex)
|
||||||
|> validate_length(:bio, max: 1000)
|
|> validate_length(:bio, max: 1000)
|
||||||
|> validate_length(:name, min: 1, max: 100)
|
|> validate_length(:name, min: 1, max: 100)
|
||||||
|
|> put_change(:info, %Pleroma.User.Info{})
|
||||||
|
|
||||||
if changeset.valid? do
|
if changeset.valid? do
|
||||||
hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
|
hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
|
||||||
|
@ -191,7 +204,7 @@ def needs_update?(%User{local: false} = user) do
|
||||||
|
|
||||||
def needs_update?(_), do: true
|
def needs_update?(_), do: true
|
||||||
|
|
||||||
def maybe_direct_follow(%User{} = follower, %User{local: true, info: %{"locked" => true}}) do
|
def maybe_direct_follow(%User{} = follower, %User{local: true, info: %{locked: true}}) do
|
||||||
{:ok, follower}
|
{:ok, follower}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -222,7 +235,7 @@ def follow(%User{} = follower, %User{info: info} = followed) do
|
||||||
ap_followers = followed.follower_address
|
ap_followers = followed.follower_address
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
following?(follower, followed) or info["deactivated"] ->
|
following?(follower, followed) or info.deactivated ->
|
||||||
{:error, "Could not follow user: #{followed.nickname} is already on your list."}
|
{:error, "Could not follow user: #{followed.nickname} is already on your list."}
|
||||||
|
|
||||||
deny_follow_blocked and blocks?(followed, follower) ->
|
deny_follow_blocked and blocks?(followed, follower) ->
|
||||||
|
@ -274,7 +287,7 @@ def following?(%User{} = follower, %User{} = followed) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def locked?(%User{} = user) do
|
def locked?(%User{} = user) do
|
||||||
user.info["locked"] || false
|
user.info.locked || false
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_by_ap_id(ap_id) do
|
def get_by_ap_id(ap_id) do
|
||||||
|
@ -411,22 +424,23 @@ def get_follow_requests(%User{} = user) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def increase_note_count(%User{} = user) do
|
def increase_note_count(%User{} = user) do
|
||||||
note_count = (user.info["note_count"] || 0) + 1
|
info_cng = User.Info.add_to_note_count(user.info, 1)
|
||||||
new_info = Map.put(user.info, "note_count", note_count)
|
|
||||||
|
|
||||||
cs = info_changeset(user, %{info: new_info})
|
cng =
|
||||||
|
change(user)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
update_and_set_cache(cs)
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def decrease_note_count(%User{} = user) do
|
def decrease_note_count(%User{} = user) do
|
||||||
note_count = user.info["note_count"] || 0
|
info_cng = User.Info.add_to_note_count(user.info, -1)
|
||||||
note_count = if note_count <= 0, do: 0, else: note_count - 1
|
|
||||||
new_info = Map.put(user.info, "note_count", note_count)
|
|
||||||
|
|
||||||
cs = info_changeset(user, %{info: new_info})
|
cng =
|
||||||
|
change(user)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
update_and_set_cache(cs)
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_note_count(%User{} = user) do
|
def update_note_count(%User{} = user) do
|
||||||
|
@ -439,11 +453,13 @@ def update_note_count(%User{} = user) do
|
||||||
|
|
||||||
note_count = Repo.one(note_count_query)
|
note_count = Repo.one(note_count_query)
|
||||||
|
|
||||||
new_info = Map.put(user.info, "note_count", note_count)
|
info_cng = User.Info.set_note_count(user.info, note_count)
|
||||||
|
|
||||||
cs = info_changeset(user, %{info: new_info})
|
cng =
|
||||||
|
change(user)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
update_and_set_cache(cs)
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_follower_count(%User{} = user) do
|
def update_follower_count(%User{} = user) do
|
||||||
|
@ -457,11 +473,15 @@ def update_follower_count(%User{} = user) do
|
||||||
|
|
||||||
follower_count = Repo.one(follower_count_query)
|
follower_count = Repo.one(follower_count_query)
|
||||||
|
|
||||||
new_info = Map.put(user.info, "follower_count", follower_count)
|
info_cng =
|
||||||
|
user.info
|
||||||
|
|> User.Info.set_follower_count(follower_count)
|
||||||
|
|
||||||
cs = info_changeset(user, %{info: new_info})
|
cng =
|
||||||
|
change(user)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
update_and_set_cache(cs)
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_users_from_set_query(ap_ids, false) do
|
def get_users_from_set_query(ap_ids, false) do
|
||||||
|
@ -545,12 +565,15 @@ def block(blocker, %User{ap_id: ap_id} = blocked) do
|
||||||
unfollow(blocked, blocker)
|
unfollow(blocked, blocker)
|
||||||
end
|
end
|
||||||
|
|
||||||
blocks = blocker.info["blocks"] || []
|
info_cng =
|
||||||
new_blocks = Enum.uniq([ap_id | blocks])
|
blocker.info
|
||||||
new_info = Map.put(blocker.info, "blocks", new_blocks)
|
|> User.Info.add_to_block(ap_id)
|
||||||
|
|
||||||
cs = User.info_changeset(blocker, %{info: new_info})
|
cng =
|
||||||
update_and_set_cache(cs)
|
change(blocker)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
# helper to handle the block given only an actor's AP id
|
# helper to handle the block given only an actor's AP id
|
||||||
|
@ -558,18 +581,21 @@ def block(blocker, %{ap_id: ap_id}) do
|
||||||
block(blocker, User.get_by_ap_id(ap_id))
|
block(blocker, User.get_by_ap_id(ap_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
def unblock(user, %{ap_id: ap_id}) do
|
def unblock(blocker, %{ap_id: ap_id}) do
|
||||||
blocks = user.info["blocks"] || []
|
info_cng =
|
||||||
new_blocks = List.delete(blocks, ap_id)
|
blocker.info
|
||||||
new_info = Map.put(user.info, "blocks", new_blocks)
|
|> User.Info.remove_from_block(ap_id)
|
||||||
|
|
||||||
cs = User.info_changeset(user, %{info: new_info})
|
cng =
|
||||||
update_and_set_cache(cs)
|
change(blocker)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def blocks?(user, %{ap_id: ap_id}) do
|
def blocks?(user, %{ap_id: ap_id}) do
|
||||||
blocks = user.info["blocks"] || []
|
blocks = user.info.blocks
|
||||||
domain_blocks = user.info["domain_blocks"] || []
|
domain_blocks = user.info.domain_blocks
|
||||||
%{host: host} = URI.parse(ap_id)
|
%{host: host} = URI.parse(ap_id)
|
||||||
|
|
||||||
Enum.member?(blocks, ap_id) ||
|
Enum.member?(blocks, ap_id) ||
|
||||||
|
@ -579,21 +605,27 @@ def blocks?(user, %{ap_id: ap_id}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def block_domain(user, domain) do
|
def block_domain(user, domain) do
|
||||||
domain_blocks = user.info["domain_blocks"] || []
|
info_cng =
|
||||||
new_blocks = Enum.uniq([domain | domain_blocks])
|
user.info
|
||||||
new_info = Map.put(user.info, "domain_blocks", new_blocks)
|
|> User.Info.add_to_domain_block(domain)
|
||||||
|
|
||||||
cs = User.info_changeset(user, %{info: new_info})
|
cng =
|
||||||
update_and_set_cache(cs)
|
change(user)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unblock_domain(user, domain) do
|
def unblock_domain(user, domain) do
|
||||||
blocks = user.info["domain_blocks"] || []
|
info_cng =
|
||||||
new_blocks = List.delete(blocks, domain)
|
user.info
|
||||||
new_info = Map.put(user.info, "domain_blocks", new_blocks)
|
|> User.Info.remove_from_domain_block(domain)
|
||||||
|
|
||||||
cs = User.info_changeset(user, %{info: new_info})
|
cng =
|
||||||
update_and_set_cache(cs)
|
change(user)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def local_user_query() do
|
def local_user_query() do
|
||||||
|
@ -613,9 +645,13 @@ def moderator_user_query() do
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate(%User{} = user, status \\ true) do
|
def deactivate(%User{} = user, status \\ true) do
|
||||||
new_info = Map.put(user.info, "deactivated", status)
|
info_cng = User.Info.set_activation_status(user.info, status)
|
||||||
cs = User.info_changeset(user, %{info: new_info})
|
|
||||||
update_and_set_cache(cs)
|
cng =
|
||||||
|
change(user)
|
||||||
|
|> put_embed(:info, info_cng)
|
||||||
|
|
||||||
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(%User{} = user) do
|
def delete(%User{} = user) do
|
||||||
|
@ -649,7 +685,7 @@ def delete(%User{} = user) do
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
end
|
end
|
||||||
|
|
||||||
def html_filter_policy(%User{info: %{"no_rich_text" => true}}) do
|
def html_filter_policy(%User{info: %{no_rich_text: true}}) do
|
||||||
Pleroma.HTML.Scrubber.TwitterText
|
Pleroma.HTML.Scrubber.TwitterText
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -683,7 +719,7 @@ def get_or_create_instance_user do
|
||||||
user
|
user
|
||||||
else
|
else
|
||||||
changes =
|
changes =
|
||||||
%User{}
|
%User{info: %User.Info{}}
|
||||||
|> cast(%{}, [:ap_id, :nickname, :local])
|
|> cast(%{}, [:ap_id, :nickname, :local])
|
||||||
|> put_change(:ap_id, relay_uri)
|
|> put_change(:ap_id, relay_uri)
|
||||||
|> put_change(:nickname, nil)
|
|> put_change(:nickname, nil)
|
||||||
|
@ -697,7 +733,7 @@ def get_or_create_instance_user do
|
||||||
|
|
||||||
# AP style
|
# AP style
|
||||||
def public_key_from_info(%{
|
def public_key_from_info(%{
|
||||||
"source_data" => %{"publicKey" => %{"publicKeyPem" => public_key_pem}}
|
source_data: %{"publicKey" => %{"publicKeyPem" => public_key_pem}}
|
||||||
}) do
|
}) do
|
||||||
key =
|
key =
|
||||||
:public_key.pem_decode(public_key_pem)
|
:public_key.pem_decode(public_key_pem)
|
||||||
|
@ -708,7 +744,7 @@ def public_key_from_info(%{
|
||||||
end
|
end
|
||||||
|
|
||||||
# OStatus Magic Key
|
# OStatus Magic Key
|
||||||
def public_key_from_info(%{"magic_key" => magic_key}) do
|
def public_key_from_info(%{magic_key: magic_key}) do
|
||||||
{:ok, Pleroma.Web.Salmon.decode_key(magic_key)}
|
{:ok, Pleroma.Web.Salmon.decode_key(magic_key)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -730,11 +766,12 @@ def insert_or_update_user(data) do
|
||||||
|> Map.put(:name, blank?(data[:name]) || data[:nickname])
|
|> Map.put(:name, blank?(data[:name]) || data[:nickname])
|
||||||
|
|
||||||
cs = User.remote_user_creation(data)
|
cs = User.remote_user_creation(data)
|
||||||
|
|
||||||
Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
|
Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ap_enabled?(%User{local: true}), do: true
|
def ap_enabled?(%User{local: true}), do: true
|
||||||
def ap_enabled?(%User{info: info}), do: info["ap_enabled"]
|
def ap_enabled?(%User{info: info}), do: info.ap_enabled
|
||||||
def ap_enabled?(_), do: false
|
def ap_enabled?(_), do: false
|
||||||
|
|
||||||
def get_or_fetch(uri_or_nickname) do
|
def get_or_fetch(uri_or_nickname) do
|
||||||
|
@ -768,4 +805,18 @@ def wait_and_refresh(timeout, %User{} = a, %User{} = b) do
|
||||||
:error
|
:error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_bio(bio, user \\ %User{info: %{source_data: %{}}}) do
|
||||||
|
mentions = Formatter.parse_mentions(bio)
|
||||||
|
tags = Formatter.parse_tags(bio)
|
||||||
|
|
||||||
|
emoji =
|
||||||
|
(user.info.source_data["tag"] || [])
|
||||||
|
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
||||||
|
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
||||||
|
{String.trim(name, ":"), url}
|
||||||
|
end)
|
||||||
|
|
||||||
|
CommonUtils.format_input(bio, mentions, tags, "text/plain") |> Formatter.emojify(emoji)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
165
lib/pleroma/user/info.ex
Normal file
165
lib/pleroma/user/info.ex
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
defmodule Pleroma.User.Info do
|
||||||
|
use Ecto.Schema
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
embedded_schema do
|
||||||
|
field(:banner, :map, default: %{})
|
||||||
|
field(:background, :map, default: %{})
|
||||||
|
field(:source_data, :map, default: %{})
|
||||||
|
field(:note_count, :integer, default: 0)
|
||||||
|
field(:follower_count, :integer, default: 0)
|
||||||
|
field(:locked, :boolean, default: false)
|
||||||
|
field(:default_scope, :string, default: "public")
|
||||||
|
field(:blocks, {:array, :string}, default: [])
|
||||||
|
field(:domain_blocks, {:array, :string}, default: [])
|
||||||
|
field(:deactivated, :boolean, default: false)
|
||||||
|
field(:no_rich_text, :boolean, default: false)
|
||||||
|
field(:ap_enabled, :boolean, default: false)
|
||||||
|
field(:is_moderator, :boolean, default: false)
|
||||||
|
field(:is_admin, :boolean, default: false)
|
||||||
|
field(:keys, :string, default: nil)
|
||||||
|
field(:settings, :map, default: nil)
|
||||||
|
field(:magic_key, :string, default: nil)
|
||||||
|
field(:uri, :string, default: nil)
|
||||||
|
field(:topic, :string, default: nil)
|
||||||
|
field(:hub, :string, default: nil)
|
||||||
|
field(:salmon, :string, default: nil)
|
||||||
|
|
||||||
|
# Found in the wild
|
||||||
|
# ap_id -> Where is this used?
|
||||||
|
# bio -> Where is this used?
|
||||||
|
# avatar -> Where is this used?
|
||||||
|
# fqn -> Where is this used?
|
||||||
|
# host -> Where is this used?
|
||||||
|
# subject _> Where is this used?
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_activation_status(info, deactivated) do
|
||||||
|
params = %{deactivated: deactivated}
|
||||||
|
|
||||||
|
info
|
||||||
|
|> cast(params, [:deactivated])
|
||||||
|
|> validate_required([:deactivated])
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_to_note_count(info, number) do
|
||||||
|
set_note_count(info, info.note_count + number)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_note_count(info, number) do
|
||||||
|
params = %{note_count: Enum.max([0, number])}
|
||||||
|
|
||||||
|
info
|
||||||
|
|> cast(params, [:note_count])
|
||||||
|
|> validate_required([:note_count])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_follower_count(info, number) do
|
||||||
|
params = %{follower_count: Enum.max([0, number])}
|
||||||
|
|
||||||
|
info
|
||||||
|
|> cast(params, [:follower_count])
|
||||||
|
|> validate_required([:follower_count])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_blocks(info, blocks) do
|
||||||
|
params = %{blocks: blocks}
|
||||||
|
|
||||||
|
info
|
||||||
|
|> cast(params, [:blocks])
|
||||||
|
|> validate_required([:blocks])
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_to_block(info, blocked) do
|
||||||
|
set_blocks(info, Enum.uniq([blocked | info.blocks]))
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_from_block(info, blocked) do
|
||||||
|
set_blocks(info, List.delete(info.blocks, blocked))
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_domain_blocks(info, domain_blocks) do
|
||||||
|
params = %{domain_blocks: domain_blocks}
|
||||||
|
|
||||||
|
info
|
||||||
|
|> cast(params, [:domain_blocks])
|
||||||
|
|> validate_required([:domain_blocks])
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_to_domain_block(info, domain_blocked) do
|
||||||
|
set_domain_blocks(info, Enum.uniq([domain_blocked | info.domain_blocks]))
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_from_domain_block(info, domain_blocked) do
|
||||||
|
set_domain_blocks(info, List.delete(info.domain_blocks, domain_blocked))
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_keys(info, keys) do
|
||||||
|
params = %{keys: keys}
|
||||||
|
|
||||||
|
info
|
||||||
|
|> cast(params, [:keys])
|
||||||
|
|> validate_required([:keys])
|
||||||
|
end
|
||||||
|
|
||||||
|
def remote_user_creation(info, params) do
|
||||||
|
info
|
||||||
|
|> cast(params, [
|
||||||
|
:ap_enabled,
|
||||||
|
:source_data,
|
||||||
|
:banner,
|
||||||
|
:locked,
|
||||||
|
:magic_key,
|
||||||
|
:uri,
|
||||||
|
:hub,
|
||||||
|
:topic,
|
||||||
|
:salmon
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_upgrade(info, params) do
|
||||||
|
info
|
||||||
|
|> cast(params, [
|
||||||
|
:ap_enabled,
|
||||||
|
:source_data,
|
||||||
|
:banner,
|
||||||
|
:locked,
|
||||||
|
:magic_key
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
def profile_update(info, params) do
|
||||||
|
info
|
||||||
|
|> cast(params, [
|
||||||
|
:locked,
|
||||||
|
:no_rich_text,
|
||||||
|
:default_scope,
|
||||||
|
:banner,
|
||||||
|
:background
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
def mastodon_profile_update(info, params) do
|
||||||
|
info
|
||||||
|
|> cast(params, [
|
||||||
|
:locked,
|
||||||
|
:banner
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_source_data(info, source_data) do
|
||||||
|
params = %{source_data: source_data}
|
||||||
|
|
||||||
|
info
|
||||||
|
|> cast(params, [:source_data])
|
||||||
|
|> validate_required([:source_data])
|
||||||
|
end
|
||||||
|
|
||||||
|
def admin_api_update(info, params) do
|
||||||
|
info
|
||||||
|
|> cast(params, [
|
||||||
|
:is_moderator,
|
||||||
|
:is_admin
|
||||||
|
])
|
||||||
|
end
|
||||||
|
end
|
|
@ -42,7 +42,7 @@ defp get_recipients(data) do
|
||||||
defp check_actor_is_active(actor) do
|
defp check_actor_is_active(actor) do
|
||||||
if not is_nil(actor) do
|
if not is_nil(actor) do
|
||||||
with user <- User.get_cached_by_ap_id(actor),
|
with user <- User.get_cached_by_ap_id(actor),
|
||||||
false <- !!user.info["deactivated"] do
|
false <- user.info.deactivated do
|
||||||
:ok
|
:ok
|
||||||
else
|
else
|
||||||
_e -> :reject
|
_e -> :reject
|
||||||
|
@ -509,8 +509,8 @@ defp restrict_recent(query, _) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do
|
defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do
|
||||||
blocks = info["blocks"] || []
|
blocks = info.blocks || []
|
||||||
domain_blocks = info["domain_blocks"] || []
|
domain_blocks = info.domain_blocks || []
|
||||||
|
|
||||||
from(
|
from(
|
||||||
activity in query,
|
activity in query,
|
||||||
|
@ -676,7 +676,7 @@ def publish(actor, activity) do
|
||||||
remote_inboxes =
|
remote_inboxes =
|
||||||
(Pleroma.Web.Salmon.remote_users(activity) ++ followers)
|
(Pleroma.Web.Salmon.remote_users(activity) ++ followers)
|
||||||
|> Enum.filter(fn user -> User.ap_enabled?(user) end)
|
|> Enum.filter(fn user -> User.ap_enabled?(user) end)
|
||||||
|> Enum.map(fn %{info: %{"source_data" => data}} ->
|
|> Enum.map(fn %{info: %{source_data: data}} ->
|
||||||
(is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"]
|
(is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"]
|
||||||
end)
|
end)
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|
@ -762,7 +762,7 @@ def fetch_and_contain_remote_object_from_id(id) do
|
||||||
Logger.info("Fetching #{id} via AP")
|
Logger.info("Fetching #{id} via AP")
|
||||||
|
|
||||||
with true <- String.starts_with?(id, "http"),
|
with true <- String.starts_with?(id, "http"),
|
||||||
{:ok, %{body: body, status_code: code}} when code in 200..299 <-
|
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
||||||
@httpoison.get(
|
@httpoison.get(
|
||||||
id,
|
id,
|
||||||
[Accept: "application/activity+json"],
|
[Accept: "application/activity+json"],
|
||||||
|
|
|
@ -23,7 +23,7 @@ defp check_reject(%{host: actor_host} = _actor_info, object) do
|
||||||
|
|
||||||
defp check_media_removal(
|
defp check_media_removal(
|
||||||
%{host: actor_host} = _actor_info,
|
%{host: actor_host} = _actor_info,
|
||||||
%{"type" => "Create", "object" => %{"attachement" => child_attachment}} = object
|
%{"type" => "Create", "object" => %{"attachment" => child_attachment}} = object
|
||||||
)
|
)
|
||||||
when length(child_attachment) > 0 do
|
when length(child_attachment) > 0 do
|
||||||
object =
|
object =
|
||||||
|
|
|
@ -447,7 +447,7 @@ def handle_incoming(
|
||||||
update_data =
|
update_data =
|
||||||
new_user_data
|
new_user_data
|
||||||
|> Map.take([:name, :bio, :avatar])
|
|> Map.take([:name, :bio, :avatar])
|
||||||
|> Map.put(:info, Map.merge(actor.info, %{"banner" => banner, "locked" => locked}))
|
|> Map.put(:info, %{"banner" => banner, "locked" => locked})
|
||||||
|
|
||||||
actor
|
actor
|
||||||
|> User.upgrade_changeset(update_data)
|
|> User.upgrade_changeset(update_data)
|
||||||
|
@ -850,10 +850,6 @@ defp user_upgrade_task(user) do
|
||||||
def upgrade_user_from_ap_id(ap_id, async \\ true) do
|
def upgrade_user_from_ap_id(ap_id, async \\ true) do
|
||||||
with %User{local: false} = user <- User.get_by_ap_id(ap_id),
|
with %User{local: false} = user <- User.get_by_ap_id(ap_id),
|
||||||
{:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id) do
|
{:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id) do
|
||||||
data =
|
|
||||||
data
|
|
||||||
|> Map.put(:info, Map.merge(user.info, data[:info]))
|
|
||||||
|
|
||||||
already_ap = User.ap_enabled?(user)
|
already_ap = User.ap_enabled?(user)
|
||||||
|
|
||||||
{:ok, user} =
|
{:ok, user} =
|
||||||
|
|
|
@ -12,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
|
||||||
# the instance itself is not a Person, but instead an Application
|
# the instance itself is not a Person, but instead an Application
|
||||||
def render("user.json", %{user: %{nickname: nil} = user}) do
|
def render("user.json", %{user: %{nickname: nil} = user}) do
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
{:ok, user} = WebFinger.ensure_keys_present(user)
|
||||||
{:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"])
|
{:ok, _, public_key} = Salmon.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)
|
||||||
public_key = :public_key.pem_encode([public_key])
|
public_key = :public_key.pem_encode([public_key])
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ def render("user.json", %{user: %{nickname: nil} = user}) do
|
||||||
|
|
||||||
def render("user.json", %{user: user}) do
|
def render("user.json", %{user: user}) do
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
{:ok, user} = WebFinger.ensure_keys_present(user)
|
||||||
{:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"])
|
{:ok, _, public_key} = Salmon.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)
|
||||||
public_key = :public_key.pem_encode([public_key])
|
public_key = :public_key.pem_encode([public_key])
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ def render("user.json", %{user: user}) do
|
||||||
"name" => user.name,
|
"name" => user.name,
|
||||||
"summary" => user.bio,
|
"summary" => user.bio,
|
||||||
"url" => user.ap_id,
|
"url" => user.ap_id,
|
||||||
"manuallyApprovesFollowers" => user.info["locked"] || false,
|
"manuallyApprovesFollowers" => user.info.locked,
|
||||||
"publicKey" => %{
|
"publicKey" => %{
|
||||||
"id" => "#{user.ap_id}#main-key",
|
"id" => "#{user.ap_id}#main-key",
|
||||||
"owner" => user.ap_id,
|
"owner" => user.ap_id,
|
||||||
|
@ -72,7 +72,7 @@ def render("user.json", %{user: user}) do
|
||||||
"type" => "Image",
|
"type" => "Image",
|
||||||
"url" => User.banner_url(user)
|
"url" => User.banner_url(user)
|
||||||
},
|
},
|
||||||
"tag" => user.info["source_data"]["tag"] || []
|
"tag" => user.info.source_data["tag"] || []
|
||||||
}
|
}
|
||||||
|> Map.merge(Utils.make_json_ld_header())
|
|> Map.merge(Utils.make_json_ld_header())
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,21 +45,29 @@ def right_add(conn, %{"permission_group" => permission_group, "nickname" => nick
|
||||||
user = User.get_by_nickname(nickname)
|
user = User.get_by_nickname(nickname)
|
||||||
|
|
||||||
info =
|
info =
|
||||||
user.info
|
%{}
|
||||||
|> Map.put("is_" <> permission_group, true)
|
|> Map.put("is_" <> permission_group, true)
|
||||||
|
|
||||||
cng = User.info_changeset(user, %{info: info})
|
info_cng = User.Info.admin_api_update(user.info, info)
|
||||||
|
|
||||||
|
cng =
|
||||||
|
Ecto.Changeset.change(user)
|
||||||
|
|> Ecto.Changeset.put_embed(:info, info_cng)
|
||||||
|
|
||||||
{:ok, user} = User.update_and_set_cache(cng)
|
{:ok, user} = User.update_and_set_cache(cng)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> json(user.info)
|
|> json(info)
|
||||||
end
|
end
|
||||||
|
|
||||||
def right_get(conn, %{"nickname" => nickname}) do
|
def right_get(conn, %{"nickname" => nickname}) do
|
||||||
user = User.get_by_nickname(nickname)
|
user = User.get_by_nickname(nickname)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> json(user.info)
|
|> json(%{
|
||||||
|
is_moderator: user.info.is_moderator,
|
||||||
|
is_admin: user.info.is_admin
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
def right_add(conn, _) do
|
def right_add(conn, _) do
|
||||||
|
@ -84,14 +92,19 @@ def right_delete(
|
||||||
user = User.get_by_nickname(nickname)
|
user = User.get_by_nickname(nickname)
|
||||||
|
|
||||||
info =
|
info =
|
||||||
user.info
|
%{}
|
||||||
|> Map.put("is_" <> permission_group, false)
|
|> Map.put("is_" <> permission_group, false)
|
||||||
|
|
||||||
cng = User.info_changeset(user, %{info: info})
|
info_cng = User.Info.admin_api_update(user.info, info)
|
||||||
|
|
||||||
|
cng =
|
||||||
|
Ecto.Changeset.change(user)
|
||||||
|
|> Ecto.Changeset.put_embed(:info, info_cng)
|
||||||
|
|
||||||
{:ok, user} = User.update_and_set_cache(cng)
|
{:ok, user} = User.update_and_set_cache(cng)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> json(user.info)
|
|> json(info)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.CommonAPI do
|
||||||
def delete(activity_id, user) do
|
def delete(activity_id, user) do
|
||||||
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
|
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
|
||||||
%Object{} = object <- Object.normalize(object_id),
|
%Object{} = object <- Object.normalize(object_id),
|
||||||
true <- user.info["is_moderator"] || user.ap_id == object.data["actor"],
|
true <- user.info.is_moderator || user.ap_id == object.data["actor"],
|
||||||
{:ok, delete} <- ActivityPub.delete(object) do
|
{:ok, delete} <- ActivityPub.delete(object) do
|
||||||
{:ok, delete}
|
{:ok, delete}
|
||||||
end
|
end
|
||||||
|
@ -135,12 +135,13 @@ def post(user, %{"status" => status} = data) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Updates the emojis for a user based on their profile
|
||||||
def update(user) do
|
def update(user) do
|
||||||
user =
|
user =
|
||||||
with emoji <- emoji_from_profile(user),
|
with emoji <- emoji_from_profile(user),
|
||||||
source_data <- (user.info["source_data"] || %{}) |> Map.put("tag", emoji),
|
source_data <- (user.info.source_data || %{}) |> Map.put("tag", emoji),
|
||||||
new_info <- Map.put(user.info, "source_data", source_data),
|
info_cng <- Pleroma.User.Info.set_source_data(user.info, source_data),
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
change <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng),
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
{:ok, user} <- User.update_and_set_cache(change) do
|
||||||
user
|
user
|
||||||
else
|
else
|
||||||
|
|
|
@ -17,7 +17,15 @@ def init(args) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def start_link() do
|
def start_link() do
|
||||||
|
enabled = Pleroma.Config.get([:retry_queue, :enabled], false)
|
||||||
|
|
||||||
|
if enabled do
|
||||||
|
Logger.info("Starting retry queue")
|
||||||
GenServer.start_link(__MODULE__, %{delivered: 0, dropped: 0}, name: __MODULE__)
|
GenServer.start_link(__MODULE__, %{delivered: 0, dropped: 0}, name: __MODULE__)
|
||||||
|
else
|
||||||
|
Logger.info("Retry queue disabled")
|
||||||
|
:ignore
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def enqueue(data, transport, retries \\ 0) do
|
def enqueue(data, transport, retries \\ 0) do
|
||||||
|
|
|
@ -65,7 +65,7 @@ def build_signing_string(headers, used_headers) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def sign(user, headers) do
|
def sign(user, headers) do
|
||||||
with {:ok, %{info: %{"keys" => keys}}} <- Pleroma.Web.WebFinger.ensure_keys_present(user),
|
with {:ok, %{info: %{keys: keys}}} <- Pleroma.Web.WebFinger.ensure_keys_present(user),
|
||||||
{:ok, private_key, _} = Pleroma.Web.Salmon.keys_from_pem(keys) do
|
{:ok, private_key, _} = Pleroma.Web.Salmon.keys_from_pem(keys) do
|
||||||
sigstring = build_signing_string(headers, Map.keys(headers))
|
sigstring = build_signing_string(headers, Map.keys(headers))
|
||||||
|
|
||||||
|
|
|
@ -32,67 +32,55 @@ def create_app(conn, params) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp add_if_present(
|
||||||
|
map,
|
||||||
|
params,
|
||||||
|
params_field,
|
||||||
|
map_field,
|
||||||
|
value_function \\ fn x -> {:ok, x} end
|
||||||
|
) do
|
||||||
|
if Map.has_key?(params, params_field) do
|
||||||
|
case value_function.(params[params_field]) do
|
||||||
|
{:ok, new_value} -> Map.put(map, map_field, new_value)
|
||||||
|
:error -> map
|
||||||
|
end
|
||||||
|
else
|
||||||
|
map
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
||||||
original_user = user
|
original_user = user
|
||||||
|
|
||||||
params =
|
user_params =
|
||||||
if bio = params["note"] do
|
%{}
|
||||||
Map.put(params, "bio", bio)
|
|> add_if_present(params, "display_name", :name)
|
||||||
|
|> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value)} end)
|
||||||
|
|> add_if_present(params, "avatar", :avatar, fn value ->
|
||||||
|
with %Plug.Upload{} <- value,
|
||||||
|
{:ok, object} <- ActivityPub.upload(value, type: :avatar) do
|
||||||
|
{:ok, object.data}
|
||||||
else
|
else
|
||||||
params
|
_ -> :error
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
params =
|
info_params =
|
||||||
if name = params["display_name"] do
|
%{}
|
||||||
Map.put(params, "name", name)
|
|> add_if_present(params, "locked", :locked, fn value -> {:ok, value == "true"} end)
|
||||||
|
|> add_if_present(params, "header", :banner, fn value ->
|
||||||
|
with %Plug.Upload{} <- value,
|
||||||
|
{:ok, object} <- ActivityPub.upload(value, type: :banner) do
|
||||||
|
{:ok, object.data}
|
||||||
else
|
else
|
||||||
params
|
_ -> :error
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
user =
|
info_cng = User.Info.mastodon_profile_update(user.info, info_params)
|
||||||
if avatar = params["avatar"] do
|
|
||||||
with %Plug.Upload{} <- avatar,
|
|
||||||
{:ok, object} <- ActivityPub.upload(avatar, type: :avatar),
|
|
||||||
change = Ecto.Changeset.change(user, %{avatar: object.data}),
|
|
||||||
{:ok, user} = User.update_and_set_cache(change) do
|
|
||||||
user
|
|
||||||
else
|
|
||||||
_e -> user
|
|
||||||
end
|
|
||||||
else
|
|
||||||
user
|
|
||||||
end
|
|
||||||
|
|
||||||
user =
|
with changeset <- User.update_changeset(user, user_params),
|
||||||
if banner = params["header"] do
|
changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng),
|
||||||
with %Plug.Upload{} <- banner,
|
|
||||||
{:ok, object} <- ActivityPub.upload(banner, type: :banner),
|
|
||||||
new_info <- Map.put(user.info, "banner", object.data),
|
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
|
||||||
user
|
|
||||||
else
|
|
||||||
_e -> user
|
|
||||||
end
|
|
||||||
else
|
|
||||||
user
|
|
||||||
end
|
|
||||||
|
|
||||||
user =
|
|
||||||
if locked = params["locked"] do
|
|
||||||
with locked <- locked == "true",
|
|
||||||
new_info <- Map.put(user.info, "locked", locked),
|
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
|
||||||
user
|
|
||||||
else
|
|
||||||
_e -> user
|
|
||||||
end
|
|
||||||
else
|
|
||||||
user
|
|
||||||
end
|
|
||||||
|
|
||||||
with changeset <- User.update_changeset(user, params),
|
|
||||||
{:ok, user} <- User.update_and_set_cache(changeset) do
|
{:ok, user} <- User.update_and_set_cache(changeset) do
|
||||||
if original_user != user do
|
if original_user != user do
|
||||||
CommonAPI.update(user)
|
CommonAPI.update(user)
|
||||||
|
@ -644,7 +632,7 @@ def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
|
||||||
|
|
||||||
# TODO: Use proper query
|
# TODO: Use proper query
|
||||||
def blocks(%{assigns: %{user: user}} = conn, _) do
|
def blocks(%{assigns: %{user: user}} = conn, _) do
|
||||||
with blocked_users <- user.info["blocks"] || [],
|
with blocked_users <- user.info.blocks || [],
|
||||||
accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do
|
accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do
|
||||||
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
|
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
|
||||||
json(conn, res)
|
json(conn, res)
|
||||||
|
@ -652,7 +640,7 @@ def blocks(%{assigns: %{user: user}} = conn, _) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def domain_blocks(%{assigns: %{user: %{info: info}}} = conn, _) do
|
def domain_blocks(%{assigns: %{user: %{info: info}}} = conn, _) do
|
||||||
json(conn, info["domain_blocks"] || [])
|
json(conn, info.domain_blocks || [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def block_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do
|
def block_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do
|
||||||
|
@ -900,11 +888,11 @@ def index(%{assigns: %{user: user}} = conn, _params) do
|
||||||
max_toot_chars: limit
|
max_toot_chars: limit
|
||||||
},
|
},
|
||||||
rights: %{
|
rights: %{
|
||||||
delete_others_notice: !!user.info["is_moderator"]
|
delete_others_notice: !!user.info.is_moderator
|
||||||
},
|
},
|
||||||
compose: %{
|
compose: %{
|
||||||
me: "#{user.id}",
|
me: "#{user.id}",
|
||||||
default_privacy: user.info["default_scope"] || "public",
|
default_privacy: user.info.default_scope,
|
||||||
default_sensitive: false
|
default_sensitive: false
|
||||||
},
|
},
|
||||||
media_attachments: %{
|
media_attachments: %{
|
||||||
|
@ -924,7 +912,7 @@ def index(%{assigns: %{user: user}} = conn, _params) do
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
settings:
|
settings:
|
||||||
Map.get(user.info, "settings") ||
|
Map.get(user.info, :settings) ||
|
||||||
%{
|
%{
|
||||||
onboarded: true,
|
onboarded: true,
|
||||||
home: %{
|
home: %{
|
||||||
|
@ -1180,7 +1168,7 @@ def suggestions(%{assigns: %{user: user}} = conn, _) do
|
||||||
user = user.nickname
|
user = user.nickname
|
||||||
url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user)
|
url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user)
|
||||||
|
|
||||||
with {:ok, %{status_code: 200, body: body}} <-
|
with {:ok, %{status: 200, body: body}} <-
|
||||||
@httpoison.get(url, [], timeout: timeout, recv_timeout: timeout),
|
@httpoison.get(url, [], timeout: timeout, recv_timeout: timeout),
|
||||||
{:ok, data} <- Jason.decode(body) do
|
{:ok, data} <- Jason.decode(body) do
|
||||||
data2 =
|
data2 =
|
||||||
|
|
|
@ -14,10 +14,10 @@ def render("account.json", %{user: user} = opts) do
|
||||||
image = User.avatar_url(user) |> MediaProxy.url()
|
image = User.avatar_url(user) |> MediaProxy.url()
|
||||||
header = User.banner_url(user) |> MediaProxy.url()
|
header = User.banner_url(user) |> MediaProxy.url()
|
||||||
user_info = User.user_info(user)
|
user_info = User.user_info(user)
|
||||||
bot = (user.info["source_data"]["type"] || "Person") in ["Application", "Service"]
|
bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"]
|
||||||
|
|
||||||
emojis =
|
emojis =
|
||||||
(user.info["source_data"]["tag"] || [])
|
(user.info.source_data["tag"] || [])
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
||||||
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
||||||
%{
|
%{
|
||||||
|
@ -29,7 +29,7 @@ def render("account.json", %{user: user} = opts) do
|
||||||
end)
|
end)
|
||||||
|
|
||||||
fields =
|
fields =
|
||||||
(user.info["source_data"]["attachment"] || [])
|
(user.info.source_data["attachment"] || [])
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
||||||
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
|
||||||
@default_proxy_opts [max_body_length: 25 * 1_048_576]
|
@default_proxy_opts [max_body_length: 25 * 1_048_576]
|
||||||
|
|
||||||
def remote(conn, params = %{"sig" => sig64, "url" => url64}) do
|
def remote(conn, params = %{"sig" => sig64, "url" => url64}) do
|
||||||
with config <- Pleroma.Config.get([:media_proxy]),
|
with config <- Pleroma.Config.get([:media_proxy], []),
|
||||||
true <- Keyword.get(config, :enabled, false),
|
true <- Keyword.get(config, :enabled, false),
|
||||||
{:ok, url} <- MediaProxy.decode_url(sig64, url64),
|
{:ok, url} <- MediaProxy.decode_url(sig64, url64),
|
||||||
filename <- Path.basename(URI.parse(url).path),
|
filename <- Path.basename(URI.parse(url).path),
|
||||||
:ok <- filename_matches(Map.has_key?(params, "filename"), conn.request_path, url) do
|
:ok <- filename_matches(Map.has_key?(params, "filename"), conn.request_path, url) do
|
||||||
ReverseProxy.call(conn, url, Keyword.get(config, :proxy_opts, @default_proxy_length))
|
ReverseProxy.call(conn, url, Keyword.get(config, :proxy_opts, @default_proxy_opts))
|
||||||
else
|
else
|
||||||
false ->
|
false ->
|
||||||
send_resp(conn, 404, Plug.Conn.Status.reason_phrase(404))
|
send_resp(conn, 404, Plug.Conn.Status.reason_phrase(404))
|
||||||
|
|
|
@ -226,25 +226,21 @@ def maybe_update_ostatus(doc, user) do
|
||||||
old_data = %{
|
old_data = %{
|
||||||
avatar: user.avatar,
|
avatar: user.avatar,
|
||||||
bio: user.bio,
|
bio: user.bio,
|
||||||
name: user.name,
|
name: user.name
|
||||||
info: user.info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
with false <- user.local,
|
with false <- user.local,
|
||||||
avatar <- make_avatar_object(doc),
|
avatar <- make_avatar_object(doc),
|
||||||
bio <- string_from_xpath("//author[1]/summary", doc),
|
bio <- string_from_xpath("//author[1]/summary", doc),
|
||||||
name <- string_from_xpath("//author[1]/poco:displayName", doc),
|
name <- string_from_xpath("//author[1]/poco:displayName", doc),
|
||||||
info <-
|
|
||||||
Map.put(user.info, "banner", make_avatar_object(doc, "header") || user.info["banner"]),
|
|
||||||
new_data <- %{
|
new_data <- %{
|
||||||
avatar: avatar || old_data.avatar,
|
avatar: avatar || old_data.avatar,
|
||||||
name: name || old_data.name,
|
name: name || old_data.name,
|
||||||
bio: bio || old_data.bio,
|
bio: bio || old_data.bio
|
||||||
info: info || old_data.info
|
|
||||||
},
|
},
|
||||||
false <- new_data == old_data do
|
false <- new_data == old_data do
|
||||||
change = Ecto.Changeset.change(user, new_data)
|
change = Ecto.Changeset.change(user, new_data)
|
||||||
Repo.update(change)
|
User.update_and_set_cache(change)
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
|
@ -350,13 +346,15 @@ def get_atom_url(body) do
|
||||||
|
|
||||||
def fetch_activity_from_atom_url(url) do
|
def fetch_activity_from_atom_url(url) do
|
||||||
with true <- String.starts_with?(url, "http"),
|
with true <- String.starts_with?(url, "http"),
|
||||||
{:ok, %{body: body, status_code: code}} when code in 200..299 <-
|
{:ok, %{body: body, status: code}} when code in 200..299 <-
|
||||||
@httpoison.get(
|
@httpoison.get(
|
||||||
url,
|
url,
|
||||||
[Accept: "application/atom+xml"],
|
[Accept: "application/atom+xml"],
|
||||||
follow_redirect: true,
|
follow_redirect: true,
|
||||||
|
adapter: [
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
recv_timeout: 20000
|
recv_timeout: 20000
|
||||||
|
]
|
||||||
) do
|
) do
|
||||||
Logger.debug("Got document from #{url}, handling...")
|
Logger.debug("Got document from #{url}, handling...")
|
||||||
handle_incoming(body)
|
handle_incoming(body)
|
||||||
|
|
|
@ -297,12 +297,6 @@ defmodule Pleroma.Web.Router do
|
||||||
post("/account/update_profile_banner", TwitterAPI.Controller, :update_banner)
|
post("/account/update_profile_banner", TwitterAPI.Controller, :update_banner)
|
||||||
post("/qvitter/update_background_image", TwitterAPI.Controller, :update_background)
|
post("/qvitter/update_background_image", TwitterAPI.Controller, :update_background)
|
||||||
|
|
||||||
post(
|
|
||||||
"/account/most_recent_notification",
|
|
||||||
TwitterAPI.Controller,
|
|
||||||
:update_most_recent_notification
|
|
||||||
)
|
|
||||||
|
|
||||||
get("/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline)
|
get("/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline)
|
||||||
get("/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline)
|
get("/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline)
|
||||||
get("/statuses/mentions", TwitterAPI.Controller, :mentions_timeline)
|
get("/statuses/mentions", TwitterAPI.Controller, :mentions_timeline)
|
||||||
|
|
|
@ -157,15 +157,17 @@ def remote_users(%{data: %{"to" => to} = data}) do
|
||||||
|> Enum.filter(fn user -> user && !user.local end)
|
|> Enum.filter(fn user -> user && !user.local end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp send_to_user(%{info: %{"salmon" => salmon}}, feed, poster) do
|
defp send_to_user(%{info: %{salmon: salmon}}, feed, poster) do
|
||||||
with {:ok, %{status_code: code}} <-
|
with {:ok, %{status: code}} <-
|
||||||
poster.(
|
poster.(
|
||||||
salmon,
|
salmon,
|
||||||
feed,
|
feed,
|
||||||
[{"Content-Type", "application/magic-envelope+xml"}],
|
[{"Content-Type", "application/magic-envelope+xml"}],
|
||||||
|
adapter: [
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
recv_timeout: 20000,
|
recv_timeout: 20000,
|
||||||
hackney: [pool: :default]
|
pool: :default
|
||||||
|
]
|
||||||
) do
|
) do
|
||||||
Logger.debug(fn -> "Pushed to #{salmon}, code #{code}" end)
|
Logger.debug(fn -> "Pushed to #{salmon}, code #{code}" end)
|
||||||
else
|
else
|
||||||
|
@ -185,7 +187,7 @@ defp send_to_user(_, _, _), do: nil
|
||||||
]
|
]
|
||||||
def publish(user, activity, poster \\ &@httpoison.post/4)
|
def publish(user, activity, poster \\ &@httpoison.post/4)
|
||||||
|
|
||||||
def publish(%{info: %{"keys" => keys}} = user, %{data: %{"type" => type}} = activity, poster)
|
def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity, poster)
|
||||||
when type in @supported_activities do
|
when type in @supported_activities do
|
||||||
feed = ActivityRepresenter.to_simple_form(activity, user, true)
|
feed = ActivityRepresenter.to_simple_form(activity, user, true)
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = ite
|
||||||
# Get the current user so we have up-to-date blocks etc.
|
# Get the current user so we have up-to-date blocks etc.
|
||||||
if socket.assigns[:user] do
|
if socket.assigns[:user] do
|
||||||
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
|
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
|
||||||
blocks = user.info["blocks"] || []
|
blocks = user.info.blocks || []
|
||||||
|
|
||||||
parent = Object.normalize(item.data["object"])
|
parent = Object.normalize(item.data["object"])
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ def push_to_socket(topics, topic, item) do
|
||||||
# Get the current user so we have up-to-date blocks etc.
|
# Get the current user so we have up-to-date blocks etc.
|
||||||
if socket.assigns[:user] do
|
if socket.assigns[:user] do
|
||||||
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
|
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
|
||||||
blocks = user.info["blocks"] || []
|
blocks = user.info.blocks || []
|
||||||
|
|
||||||
unless item.actor in blocks do
|
unless item.actor in blocks do
|
||||||
send(socket.transport_pid, {:text, represent_update(item, user)})
|
send(socket.transport_pid, {:text, represent_update(item, user)})
|
||||||
|
|
|
@ -132,7 +132,7 @@ def register_user(params) do
|
||||||
params = %{
|
params = %{
|
||||||
nickname: params["nickname"],
|
nickname: params["nickname"],
|
||||||
name: params["fullname"],
|
name: params["fullname"],
|
||||||
bio: params["bio"],
|
bio: User.parse_bio(params["bio"]),
|
||||||
email: params["email"],
|
email: params["email"],
|
||||||
password: params["password"],
|
password: params["password"],
|
||||||
password_confirmation: params["confirm"]
|
password_confirmation: params["confirm"]
|
||||||
|
@ -148,7 +148,7 @@ def register_user(params) do
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
registrations_open || (!is_nil(token) && !token.used) ->
|
registrations_open || (!is_nil(token) && !token.used) ->
|
||||||
changeset = User.register_changeset(%User{}, params)
|
changeset = User.register_changeset(%User{info: %{}}, params)
|
||||||
|
|
||||||
with {:ok, user} <- Repo.insert(changeset) do
|
with {:ok, user} <- Repo.insert(changeset) do
|
||||||
!registrations_open && UserInviteToken.mark_as_used(token.token)
|
!registrations_open && UserInviteToken.mark_as_used(token.token)
|
||||||
|
@ -279,14 +279,6 @@ def conversation_id_to_context(id) do
|
||||||
|
|
||||||
def get_external_profile(for_user, uri) do
|
def get_external_profile(for_user, uri) do
|
||||||
with %User{} = user <- User.get_or_fetch(uri) do
|
with %User{} = user <- User.get_or_fetch(uri) do
|
||||||
spawn(fn ->
|
|
||||||
with url <- user.info["topic"],
|
|
||||||
{:ok, %{body: body}} <-
|
|
||||||
@httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do
|
|
||||||
OStatus.handle_incoming(body)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
{:ok, UserView.render("show.json", %{user: user, for: for_user})}
|
{:ok, UserView.render("show.json", %{user: user, for: for_user})}
|
||||||
else
|
else
|
||||||
_e ->
|
_e ->
|
||||||
|
|
|
@ -300,9 +300,10 @@ def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
||||||
|
|
||||||
def update_banner(%{assigns: %{user: user}} = conn, params) do
|
def update_banner(%{assigns: %{user: user}} = conn, params) do
|
||||||
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
|
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
|
||||||
new_info <- Map.put(user.info, "banner", object.data),
|
new_info <- %{"banner" => object.data},
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
info_cng <- User.Info.profile_update(user.info, new_info),
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng),
|
||||||
|
{:ok, user} <- User.update_and_set_cache(changeset) do
|
||||||
CommonAPI.update(user)
|
CommonAPI.update(user)
|
||||||
%{"url" => [%{"href" => href} | _]} = object.data
|
%{"url" => [%{"href" => href} | _]} = object.data
|
||||||
response = %{url: href} |> Jason.encode!()
|
response = %{url: href} |> Jason.encode!()
|
||||||
|
@ -314,9 +315,10 @@ def update_banner(%{assigns: %{user: user}} = conn, params) do
|
||||||
|
|
||||||
def update_background(%{assigns: %{user: user}} = conn, params) do
|
def update_background(%{assigns: %{user: user}} = conn, params) do
|
||||||
with {:ok, object} <- ActivityPub.upload(params, type: :background),
|
with {:ok, object} <- ActivityPub.upload(params, type: :background),
|
||||||
new_info <- Map.put(user.info, "background", object.data),
|
new_info <- %{"background" => object.data},
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
info_cng <- User.Info.profile_update(user.info, new_info),
|
||||||
{:ok, _user} <- User.update_and_set_cache(change) do
|
changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng),
|
||||||
|
{:ok, _user} <- User.update_and_set_cache(changeset) do
|
||||||
%{"url" => [%{"href" => href} | _]} = object.data
|
%{"url" => [%{"href" => href} | _]} = object.data
|
||||||
response = %{url: href} |> Jason.encode!()
|
response = %{url: href} |> Jason.encode!()
|
||||||
|
|
||||||
|
@ -338,20 +340,6 @@ def external_profile(%{assigns: %{user: current_user}} = conn, %{"profileurl" =>
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_most_recent_notification(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
|
||||||
with id when is_number(id) <- String.to_integer(id),
|
|
||||||
info <- user.info,
|
|
||||||
mrn <- max(id, user.info["most_recent_notification"] || 0),
|
|
||||||
updated_info <- Map.put(info, "most_recent_notification", mrn),
|
|
||||||
changeset <- User.info_changeset(user, %{info: updated_info}),
|
|
||||||
{:ok, _user} <- User.update_and_set_cache(changeset) do
|
|
||||||
conn
|
|
||||||
|> json_reply(200, Jason.encode!(mrn))
|
|
||||||
else
|
|
||||||
_e -> bad_request_reply(conn, "Can't update.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def followers(conn, params) do
|
def followers(conn, params) do
|
||||||
with {:ok, user} <- TwitterAPI.get_user(conn.assigns[:user], params),
|
with {:ok, user} <- TwitterAPI.get_user(conn.assigns[:user], params),
|
||||||
{:ok, followers} <- User.get_followers(user) do
|
{:ok, followers} <- User.get_followers(user) do
|
||||||
|
@ -439,67 +427,41 @@ def raw_empty_array(conn, _params) do
|
||||||
json(conn, [])
|
json(conn, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_profile(%{assigns: %{user: user}} = conn, params) do
|
defp build_info_cng(user, params) do
|
||||||
params =
|
info_params =
|
||||||
if bio = params["description"] do
|
["no_rich_text", "locked"]
|
||||||
mentions = Formatter.parse_mentions(bio)
|
|> Enum.reduce(%{}, fn key, res ->
|
||||||
tags = Formatter.parse_tags(bio)
|
if value = params[key] do
|
||||||
|
Map.put(res, key, value == "true")
|
||||||
emoji =
|
else
|
||||||
(user.info["source_data"]["tag"] || [])
|
res
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
end
|
||||||
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
|
||||||
{String.trim(name, ":"), url}
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain")
|
info_params =
|
||||||
Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
|
if value = params["default_scope"] do
|
||||||
|
Map.put(info_params, "default_scope", value)
|
||||||
|
else
|
||||||
|
info_params
|
||||||
|
end
|
||||||
|
|
||||||
|
User.Info.profile_update(user.info, info_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_profile_bio(user, params) do
|
||||||
|
if bio = params["description"] do
|
||||||
|
Map.put(params, "bio", User.parse_bio(bio, user))
|
||||||
else
|
else
|
||||||
params
|
params
|
||||||
end
|
end
|
||||||
|
|
||||||
user =
|
|
||||||
if locked = params["locked"] do
|
|
||||||
with locked <- locked == "true",
|
|
||||||
new_info <- Map.put(user.info, "locked", locked),
|
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
|
||||||
user
|
|
||||||
else
|
|
||||||
_e -> user
|
|
||||||
end
|
|
||||||
else
|
|
||||||
user
|
|
||||||
end
|
end
|
||||||
|
|
||||||
user =
|
def update_profile(%{assigns: %{user: user}} = conn, params) do
|
||||||
if no_rich_text = params["no_rich_text"] do
|
params = parse_profile_bio(user, params)
|
||||||
with no_rich_text <- no_rich_text == "true",
|
info_cng = build_info_cng(user, params)
|
||||||
new_info <- Map.put(user.info, "no_rich_text", no_rich_text),
|
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
|
||||||
user
|
|
||||||
else
|
|
||||||
_e -> user
|
|
||||||
end
|
|
||||||
else
|
|
||||||
user
|
|
||||||
end
|
|
||||||
|
|
||||||
user =
|
|
||||||
if default_scope = params["default_scope"] do
|
|
||||||
with new_info <- Map.put(user.info, "default_scope", default_scope),
|
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
|
||||||
user
|
|
||||||
else
|
|
||||||
_e -> user
|
|
||||||
end
|
|
||||||
else
|
|
||||||
user
|
|
||||||
end
|
|
||||||
|
|
||||||
with changeset <- User.update_changeset(user, params),
|
with changeset <- User.update_changeset(user, params),
|
||||||
|
changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng),
|
||||||
{:ok, user} <- User.update_and_set_cache(changeset) do
|
{:ok, user} <- User.update_and_set_cache(changeset) do
|
||||||
CommonAPI.update(user)
|
CommonAPI.update(user)
|
||||||
render(conn, UserView, "user.json", %{user: user, for: user})
|
render(conn, UserView, "user.json", %{user: user, for: user})
|
||||||
|
|
|
@ -31,7 +31,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
user_info = User.get_cached_user_info(user)
|
user_info = User.get_cached_user_info(user)
|
||||||
|
|
||||||
emoji =
|
emoji =
|
||||||
(user.info["source_data"]["tag"] || [])
|
(user.info.source_data["tag"] || [])
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
||||||
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
||||||
{String.trim(name, ":"), url}
|
{String.trim(name, ":"), url}
|
||||||
|
@ -40,7 +40,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
# ``fields`` is an array of mastodon profile field, containing ``{"name": "…", "value": "…"}``.
|
# ``fields`` is an array of mastodon profile field, containing ``{"name": "…", "value": "…"}``.
|
||||||
# For example: [{"name": "Pronoun", "value": "she/her"}, …]
|
# For example: [{"name": "Pronoun", "value": "she/her"}, …]
|
||||||
fields =
|
fields =
|
||||||
(user.info["source_data"]["attachment"] || [])
|
(user.info.source_data["attachment"] || [])
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
||||||
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
||||||
|
|
||||||
|
@ -66,17 +66,17 @@ def render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
"profile_image_url_profile_size" => image,
|
"profile_image_url_profile_size" => image,
|
||||||
"profile_image_url_original" => image,
|
"profile_image_url_original" => image,
|
||||||
"rights" => %{
|
"rights" => %{
|
||||||
"delete_others_notice" => !!user.info["is_moderator"]
|
"delete_others_notice" => !!user.info.is_moderator
|
||||||
},
|
},
|
||||||
"screen_name" => user.nickname,
|
"screen_name" => user.nickname,
|
||||||
"statuses_count" => user_info[:note_count],
|
"statuses_count" => user_info[:note_count],
|
||||||
"statusnet_profile_url" => user.ap_id,
|
"statusnet_profile_url" => user.ap_id,
|
||||||
"cover_photo" => User.banner_url(user) |> MediaProxy.url(),
|
"cover_photo" => User.banner_url(user) |> MediaProxy.url(),
|
||||||
"background_image" => image_url(user.info["background"]) |> MediaProxy.url(),
|
"background_image" => image_url(user.info.background) |> MediaProxy.url(),
|
||||||
"is_local" => user.local,
|
"is_local" => user.local,
|
||||||
"locked" => !!user.info["locked"],
|
"locked" => user.info.locked,
|
||||||
"default_scope" => user.info["default_scope"] || "public",
|
"default_scope" => user.info.default_scope,
|
||||||
"no_rich_text" => user.info["no_rich_text"] || false,
|
"no_rich_text" => user.info.no_rich_text,
|
||||||
"fields" => fields
|
"fields" => fields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do
|
||||||
|
|
||||||
def represent_user(user, "JSON") do
|
def represent_user(user, "JSON") do
|
||||||
{:ok, user} = ensure_keys_present(user)
|
{:ok, user} = ensure_keys_present(user)
|
||||||
{:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"])
|
{:ok, _private, public} = Salmon.keys_from_pem(user.info.keys)
|
||||||
magic_key = Salmon.encode_key(public)
|
magic_key = Salmon.encode_key(public)
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
@ -83,7 +83,7 @@ def represent_user(user, "JSON") do
|
||||||
|
|
||||||
def represent_user(user, "XML") do
|
def represent_user(user, "XML") do
|
||||||
{:ok, user} = ensure_keys_present(user)
|
{:ok, user} = ensure_keys_present(user)
|
||||||
{:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"])
|
{:ok, _private, public} = Salmon.keys_from_pem(user.info.keys)
|
||||||
magic_key = Salmon.encode_key(public)
|
magic_key = Salmon.encode_key(public)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -113,16 +113,22 @@ def represent_user(user, "XML") do
|
||||||
|
|
||||||
# This seems a better fit in Salmon
|
# This seems a better fit in Salmon
|
||||||
def ensure_keys_present(user) do
|
def ensure_keys_present(user) do
|
||||||
info = user.info || %{}
|
info = user.info
|
||||||
|
|
||||||
if info["keys"] do
|
if info.keys do
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
else
|
else
|
||||||
{:ok, pem} = Salmon.generate_rsa_pem()
|
{:ok, pem} = Salmon.generate_rsa_pem()
|
||||||
info = Map.put(info, "keys", pem)
|
|
||||||
|
|
||||||
Ecto.Changeset.change(user, info: info)
|
info_cng =
|
||||||
|> User.update_and_set_cache()
|
info
|
||||||
|
|> Pleroma.User.Info.set_keys(pem)
|
||||||
|
|
||||||
|
cng =
|
||||||
|
Ecto.Changeset.change(user)
|
||||||
|
|> Ecto.Changeset.put_embed(:info, info_cng)
|
||||||
|
|
||||||
|
User.update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -214,7 +220,7 @@ def get_template_from_xml(body) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_lrdd_template(domain) do
|
def find_lrdd_template(domain) do
|
||||||
with {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <-
|
with {:ok, %{status: status, body: body}} when status in 200..299 <-
|
||||||
@httpoison.get("http://#{domain}/.well-known/host-meta", [], follow_redirect: true) do
|
@httpoison.get("http://#{domain}/.well-known/host-meta", [], follow_redirect: true) do
|
||||||
get_template_from_xml(body)
|
get_template_from_xml(body)
|
||||||
else
|
else
|
||||||
|
@ -253,7 +259,7 @@ def finger(account) do
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
[Accept: "application/xrd+xml,application/jrd+json"],
|
||||||
follow_redirect: true
|
follow_redirect: true
|
||||||
),
|
),
|
||||||
{:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- response do
|
{:ok, %{status: status, body: body}} when status in 200..299 <- response do
|
||||||
doc = XML.parse_document(body)
|
doc = XML.parse_document(body)
|
||||||
|
|
||||||
if doc != :error do
|
if doc != :error do
|
||||||
|
|
|
@ -146,7 +146,7 @@ defp valid_topic(%{"hub.topic" => topic}, user) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do
|
def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do
|
||||||
topic = subscribed.info["topic"]
|
topic = subscribed.info.topic
|
||||||
# FIXME: Race condition, use transactions
|
# FIXME: Race condition, use transactions
|
||||||
{:ok, subscription} =
|
{:ok, subscription} =
|
||||||
with subscription when not is_nil(subscription) <-
|
with subscription when not is_nil(subscription) <-
|
||||||
|
@ -158,7 +158,7 @@ def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do
|
||||||
_e ->
|
_e ->
|
||||||
subscription = %WebsubClientSubscription{
|
subscription = %WebsubClientSubscription{
|
||||||
topic: topic,
|
topic: topic,
|
||||||
hub: subscribed.info["hub"],
|
hub: subscribed.info.hub,
|
||||||
subscribers: [subscriber.ap_id],
|
subscribers: [subscriber.ap_id],
|
||||||
state: "requested",
|
state: "requested",
|
||||||
secret: :crypto.strong_rand_bytes(8) |> Base.url_encode64(),
|
secret: :crypto.strong_rand_bytes(8) |> Base.url_encode64(),
|
||||||
|
@ -173,7 +173,7 @@ def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do
|
||||||
|
|
||||||
def gather_feed_data(topic, getter \\ &@httpoison.get/1) do
|
def gather_feed_data(topic, getter \\ &@httpoison.get/1) do
|
||||||
with {:ok, response} <- getter.(topic),
|
with {:ok, response} <- getter.(topic),
|
||||||
status_code when status_code in 200..299 <- response.status_code,
|
status when status in 200..299 <- response.status,
|
||||||
body <- response.body,
|
body <- response.body,
|
||||||
doc <- XML.parse_document(body),
|
doc <- XML.parse_document(body),
|
||||||
uri when not is_nil(uri) <- XML.string_from_xpath("/feed/author[1]/uri", doc),
|
uri when not is_nil(uri) <- XML.string_from_xpath("/feed/author[1]/uri", doc),
|
||||||
|
@ -221,7 +221,7 @@ def request_subscription(websub, poster \\ &@httpoison.post/3, timeout \\ 10_000
|
||||||
|
|
||||||
task = Task.async(websub_checker)
|
task = Task.async(websub_checker)
|
||||||
|
|
||||||
with {:ok, %{status_code: 202}} <-
|
with {:ok, %{status: 202}} <-
|
||||||
poster.(websub.hub, {:form, data}, "Content-type": "application/x-www-form-urlencoded"),
|
poster.(websub.hub, {:form, data}, "Content-type": "application/x-www-form-urlencoded"),
|
||||||
{:ok, websub} <- Task.yield(task, timeout) do
|
{:ok, websub} <- Task.yield(task, timeout) do
|
||||||
{:ok, websub}
|
{:ok, websub}
|
||||||
|
@ -257,7 +257,7 @@ def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret}) d
|
||||||
signature = sign(secret || "", xml)
|
signature = sign(secret || "", xml)
|
||||||
Logger.info(fn -> "Pushing #{topic} to #{callback}" end)
|
Logger.info(fn -> "Pushing #{topic} to #{callback}" end)
|
||||||
|
|
||||||
with {:ok, %{status_code: code}} <-
|
with {:ok, %{status: code}} <-
|
||||||
@httpoison.post(
|
@httpoison.post(
|
||||||
callback,
|
callback,
|
||||||
xml,
|
xml,
|
||||||
|
@ -265,9 +265,11 @@ def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret}) d
|
||||||
{"Content-Type", "application/atom+xml"},
|
{"Content-Type", "application/atom+xml"},
|
||||||
{"X-Hub-Signature", "sha1=#{signature}"}
|
{"X-Hub-Signature", "sha1=#{signature}"}
|
||||||
],
|
],
|
||||||
|
adapter: [
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
recv_timeout: 20000,
|
recv_timeout: 20000,
|
||||||
hackney: [pool: :default]
|
pool: :default
|
||||||
|
]
|
||||||
) do
|
) do
|
||||||
Logger.info(fn -> "Pushed to #{callback}, code #{code}" end)
|
Logger.info(fn -> "Pushed to #{callback}, code #{code}" end)
|
||||||
{:ok, code}
|
{:ok, code}
|
||||||
|
|
1
mix.exs
1
mix.exs
|
@ -56,6 +56,7 @@ defp deps do
|
||||||
{:calendar, "~> 0.17.4"},
|
{:calendar, "~> 0.17.4"},
|
||||||
{:cachex, "~> 3.0.2"},
|
{:cachex, "~> 3.0.2"},
|
||||||
{:httpoison, "~> 1.2.0"},
|
{:httpoison, "~> 1.2.0"},
|
||||||
|
{:tesla, "~> 1.2"},
|
||||||
{:jason, "~> 1.0"},
|
{:jason, "~> 1.0"},
|
||||||
{:mogrify, "~> 0.6.1"},
|
{:mogrify, "~> 0.6.1"},
|
||||||
{:ex_aws, "~> 2.0"},
|
{:ex_aws, "~> 2.0"},
|
||||||
|
|
3
mix.lock
3
mix.lock
|
@ -17,6 +17,7 @@
|
||||||
"eternal": {:hex, :eternal, "1.2.0", "e2a6b6ce3b8c248f7dc31451aefca57e3bdf0e48d73ae5043229380a67614c41", [:mix], [], "hexpm"},
|
"eternal": {:hex, :eternal, "1.2.0", "e2a6b6ce3b8c248f7dc31451aefca57e3bdf0e48d73ae5043229380a67614c41", [:mix], [], "hexpm"},
|
||||||
"ex_aws": {:hex, :ex_aws, "2.1.0", "b92651527d6c09c479f9013caa9c7331f19cba38a650590d82ebf2c6c16a1d8a", [:mix], [{:configparser_ex, "~> 2.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.1.0", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"},
|
"ex_aws": {:hex, :ex_aws, "2.1.0", "b92651527d6c09c479f9013caa9c7331f19cba38a650590d82ebf2c6c16a1d8a", [:mix], [{:configparser_ex, "~> 2.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.1.0", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"ex_aws_s3": {:hex, :ex_aws_s3, "2.0.1", "9e09366e77f25d3d88c5393824e613344631be8db0d1839faca49686e99b6704", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"},
|
"ex_aws_s3": {:hex, :ex_aws_s3, "2.0.1", "9e09366e77f25d3d88c5393824e613344631be8db0d1839faca49686e99b6704", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
|
"ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"ex_machina": {:hex, :ex_machina, "2.2.0", "fec496331e04fc2db2a1a24fe317c12c0c4a50d2beb8ebb3531ed1f0d84be0ed", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
"ex_machina": {:hex, :ex_machina, "2.2.0", "fec496331e04fc2db2a1a24fe317c12c0c4a50d2beb8ebb3531ed1f0d84be0ed", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"},
|
"gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"},
|
||||||
"hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
"hackney": {:hex, :hackney, "1.13.0", "24edc8cd2b28e1c652593833862435c80661834f6c9344e84b6a2255e7aeef03", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
"idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
"idna": {:hex, :idna, "5.1.2", "e21cb58a09f0228a9e0b95eaa1217f1bcfc31a1aaa6e1fdf2f53a33f7dbd9494", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
"jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
"makeup": {:hex, :makeup, "0.5.5", "9e08dfc45280c5684d771ad58159f718a7b5788596099bdfb0284597d368a882", [:mix], [{:nimble_parsec, "~> 0.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"makeup_elixir": {:hex, :makeup_elixir, "0.10.0", "0f09c2ddf352887a956d84f8f7e702111122ca32fbbc84c2f0569b8b65cbf7fa", [:mix], [{:makeup, "~> 0.5.5", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"meck": {:hex, :meck, "0.8.9", "64c5c0bd8bcca3a180b44196265c8ed7594e16bcc845d0698ec6b4e577f48188", [:rebar3], [], "hexpm"},
|
"meck": {:hex, :meck, "0.8.9", "64c5c0bd8bcca3a180b44196265c8ed7594e16bcc845d0698ec6b4e577f48188", [:rebar3], [], "hexpm"},
|
||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||||
"mime": {:hex, :mime, "1.3.0", "5e8d45a39e95c650900d03f897fbf99ae04f60ab1daa4a34c7a20a5151b7a5fe", [:mix], [], "hexpm"},
|
"mime": {:hex, :mime, "1.3.0", "5e8d45a39e95c650900d03f897fbf99ae04f60ab1daa4a34c7a20a5151b7a5fe", [:mix], [], "hexpm"},
|
||||||
|
@ -45,6 +47,7 @@
|
||||||
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
|
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
|
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
|
||||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
|
||||||
|
"tesla": {:hex, :tesla, "1.2.1", "864783cc27f71dd8c8969163704752476cec0f3a51eb3b06393b3971dc9733ff", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"tzdata": {:hex, :tzdata, "0.5.17", "50793e3d85af49736701da1a040c415c97dc1caf6464112fd9bd18f425d3053b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
"tzdata": {:hex, :tzdata, "0.5.17", "50793e3d85af49736701da1a040c415c97dc1caf6464112fd9bd18f425d3053b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.AddUUIDExtension do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
execute("create extension if not exists \"uuid-ossp\"")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.AddUUIDsToUserInfo do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
execute("update users set info = jsonb_set(info, '{\"id\"}', to_jsonb(uuid_generate_v4()))")
|
||||||
|
end
|
||||||
|
end
|
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.0808aeafc6252b3050ea95b17dcaff1a.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.34667c2817916147413f.js></script><script type=text/javascript src=/static/js/vendor.32c621c7157f34c20923.js></script><script type=text/javascript src=/static/js/app.065638d22ade92dea420.js></script></body></html>
|
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.0808aeafc6252b3050ea95b17dcaff1a.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.18df0da570d88ba76ec5.js></script><script type=text/javascript src=/static/js/vendor.0e895ca116d5ba12f2b6.js></script><script type=text/javascript src=/static/js/app.3f7c9aaedc6b87fa9653.js></script></body></html>
|
|
@ -11,6 +11,8 @@
|
||||||
"scopeOptionsEnabled": false,
|
"scopeOptionsEnabled": false,
|
||||||
"formattingOptionsEnabled": false,
|
"formattingOptionsEnabled": false,
|
||||||
"collapseMessageWithSubject": false,
|
"collapseMessageWithSubject": false,
|
||||||
|
"scopeCopy": false,
|
||||||
|
"subjectLineBehavior": "email",
|
||||||
"hidePostStats": false,
|
"hidePostStats": false,
|
||||||
"hideUserStats": false,
|
"hideUserStats": false,
|
||||||
"loginMethod": "password"
|
"loginMethod": "password"
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
priv/static/static/js/app.3f7c9aaedc6b87fa9653.js
Normal file
11
priv/static/static/js/app.3f7c9aaedc6b87fa9653.js
Normal file
File diff suppressed because one or more lines are too long
1
priv/static/static/js/app.3f7c9aaedc6b87fa9653.js.map
Normal file
1
priv/static/static/js/app.3f7c9aaedc6b87fa9653.js.map
Normal file
File diff suppressed because one or more lines are too long
2
priv/static/static/js/manifest.18df0da570d88ba76ec5.js
Normal file
2
priv/static/static/js/manifest.18df0da570d88ba76ec5.js
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
!function(e){function t(a){if(r[a])return r[a].exports;var n=r[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var a=window.webpackJsonp;window.webpackJsonp=function(c,o){for(var p,l,s=0,i=[];s<c.length;s++)l=c[s],n[l]&&i.push.apply(i,n[l]),n[l]=0;for(p in o)Object.prototype.hasOwnProperty.call(o,p)&&(e[p]=o[p]);for(a&&a(c,o);i.length;)i.shift().call(null,t);if(o[0])return r[0]=0,t(0)};var r={},n={0:0};t.e=function(e,a){if(0===n[e])return a.call(null,t);if(void 0!==n[e])n[e].push(a);else{n[e]=[a];var r=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.src=t.p+"static/js/"+e+"."+{1:"0e895ca116d5ba12f2b6",2:"3f7c9aaedc6b87fa9653"}[e]+".js",r.appendChild(c)}},t.m=e,t.c=r,t.p="/"}([]);
|
||||||
|
//# sourceMappingURL=manifest.18df0da570d88ba76ec5.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,2 +0,0 @@
|
||||||
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r=window.webpackJsonp;window.webpackJsonp=function(c,o){for(var p,l,s=0,i=[];s<c.length;s++)l=c[s],a[l]&&i.push.apply(i,a[l]),a[l]=0;for(p in o)Object.prototype.hasOwnProperty.call(o,p)&&(e[p]=o[p]);for(r&&r(c,o);i.length;)i.shift().call(null,t);if(o[0])return n[0]=0,t(0)};var n={},a={0:0};t.e=function(e,r){if(0===a[e])return r.call(null,t);if(void 0!==a[e])a[e].push(r);else{a[e]=[r];var n=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.src=t.p+"static/js/"+e+"."+{1:"32c621c7157f34c20923",2:"065638d22ade92dea420"}[e]+".js",n.appendChild(c)}},t.m=e,t.c=n,t.p="/"}([]);
|
|
||||||
//# sourceMappingURL=manifest.34667c2817916147413f.js.map
|
|
34
priv/static/static/js/vendor.0e895ca116d5ba12f2b6.js
Normal file
34
priv/static/static/js/vendor.0e895ca116d5ba12f2b6.js
Normal file
File diff suppressed because one or more lines are too long
1
priv/static/static/js/vendor.0e895ca116d5ba12f2b6.js.map
Normal file
1
priv/static/static/js/vendor.0e895ca116d5ba12f2b6.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
test/fixtures/httpoison_mock/framatube.org_host_meta
vendored
Normal file
2
test/fixtures/httpoison_mock/framatube.org_host_meta
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><hm:Host xmlns:hm="http://host-meta.net/xrd/1.0">framatube.org</hm:Host><Link rel="lrdd" template="http://framatube.org/main/xrd?uri={uri}"><Title>Resource Descriptor</Title></Link></XRD>
|
10
test/fixtures/httpoison_mock/gerzilla.de_host_meta
vendored
Normal file
10
test/fixtures/httpoison_mock/gerzilla.de_host_meta
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?><XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'
|
||||||
|
xmlns:hm='http://host-meta.net/xrd/1.0'>
|
||||||
|
|
||||||
|
<hm:Host>gerzilla.de</hm:Host>
|
||||||
|
|
||||||
|
<Link rel='lrdd' type="application/xrd+xml" template='https://gerzilla.de/xrd/?uri={uri}' />
|
||||||
|
<Link rel="http://oexchange.org/spec/0.8/rel/resident-target" type="application/xrd+xml"
|
||||||
|
href="https://gerzilla.de/oexchange/xrd" />
|
||||||
|
|
||||||
|
</XRD>
|
2
test/fixtures/httpoison_mock/gnusocial.de_host_meta
vendored
Normal file
2
test/fixtures/httpoison_mock/gnusocial.de_host_meta
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><hm:Host xmlns:hm="http://host-meta.net/xrd/1.0">gnusocial.de</hm:Host><Link rel="lrdd" template="http://gnusocial.de/main/xrd?uri={uri}"><Title>Resource Descriptor</Title></Link></XRD>
|
|
@ -5,6 +5,11 @@ defmodule Pleroma.FormatterTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
describe ".add_hashtag_links" do
|
describe ".add_hashtag_links" do
|
||||||
test "turns hashtags into links" do
|
test "turns hashtags into links" do
|
||||||
text = "I love #cofe and #2hu"
|
text = "I love #cofe and #2hu"
|
||||||
|
@ -110,7 +115,7 @@ test "gives a replacement for user links" do
|
||||||
archaeme =
|
archaeme =
|
||||||
insert(:user, %{
|
insert(:user, %{
|
||||||
nickname: "archaeme",
|
nickname: "archaeme",
|
||||||
info: %{"source_data" => %{"url" => "https://archeme/@archaeme"}}
|
info: %Pleroma.User.Info{source_data: %{"url" => "https://archeme/@archaeme"}}
|
||||||
})
|
})
|
||||||
|
|
||||||
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
|
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
|
||||||
|
|
55
test/http_test.exs
Normal file
55
test/http_test.exs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
defmodule Pleroma.HTTPTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn
|
||||||
|
%{
|
||||||
|
method: :get,
|
||||||
|
url: "http://example.com/hello",
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
} ->
|
||||||
|
json(%{"my" => "data"})
|
||||||
|
|
||||||
|
%{method: :get, url: "http://example.com/hello"} ->
|
||||||
|
%Tesla.Env{status: 200, body: "hello"}
|
||||||
|
|
||||||
|
%{method: :post, url: "http://example.com/world"} ->
|
||||||
|
%Tesla.Env{status: 200, body: "world"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "get/1" do
|
||||||
|
test "returns successfully result" do
|
||||||
|
assert Pleroma.HTTP.get("http://example.com/hello") == {
|
||||||
|
:ok,
|
||||||
|
%Tesla.Env{status: 200, body: "hello"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "get/2 (with headers)" do
|
||||||
|
test "returns successfully result for json content-type" do
|
||||||
|
assert Pleroma.HTTP.get("http://example.com/hello", [{"content-type", "application/json"}]) ==
|
||||||
|
{
|
||||||
|
:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: "{\"my\":\"data\"}",
|
||||||
|
headers: [{"content-type", "application/json"}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "post/2" do
|
||||||
|
test "returns successfully result" do
|
||||||
|
assert Pleroma.HTTP.post("http://example.com/world", "") == {
|
||||||
|
:ok,
|
||||||
|
%Tesla.Env{status: 200, body: "world"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -13,7 +13,7 @@ test "doesn't do anything if the user isn't set", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with a user that is deactivated, it removes that user", %{conn: conn} do
|
test "with a user that is deactivated, it removes that user", %{conn: conn} do
|
||||||
user = insert(:user, info: %{"deactivated" => true})
|
user = insert(:user, info: %{deactivated: true})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -5,7 +5,7 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
test "accepts a user that is admin", %{conn: conn} do
|
test "accepts a user that is admin", %{conn: conn} do
|
||||||
user = insert(:user, info: %{"is_admin" => true})
|
user = insert(:user, info: %{is_admin: true})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
|
|
@ -7,7 +7,8 @@ def user_factory do
|
||||||
email: sequence(:email, &"user#{&1}@example.com"),
|
email: sequence(:email, &"user#{&1}@example.com"),
|
||||||
nickname: sequence(:nickname, &"nick#{&1}"),
|
nickname: sequence(:nickname, &"nick#{&1}"),
|
||||||
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
|
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
|
||||||
bio: sequence(:bio, &"Tester Number #{&1}")
|
bio: sequence(:bio, &"Tester Number #{&1}"),
|
||||||
|
info: %{}
|
||||||
}
|
}
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
675
test/support/http_request_mock.ex
Normal file
675
test/support/http_request_mock.ex
Normal file
|
@ -0,0 +1,675 @@
|
||||||
|
defmodule HttpRequestMock do
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
def request(
|
||||||
|
%Tesla.Env{
|
||||||
|
url: url,
|
||||||
|
method: method,
|
||||||
|
headers: headers,
|
||||||
|
query: query,
|
||||||
|
body: body
|
||||||
|
} = _env
|
||||||
|
) do
|
||||||
|
with {:ok, res} <- apply(__MODULE__, method, [url, query, body, headers]) do
|
||||||
|
res
|
||||||
|
else
|
||||||
|
{_, r} = error ->
|
||||||
|
# Logger.warn(r)
|
||||||
|
error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET Requests
|
||||||
|
#
|
||||||
|
def get(url, query \\ [], body \\ [], headers \\ [])
|
||||||
|
|
||||||
|
def get("https://osada.macgirvin.com/channel/mike", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!("test/fixtures/httpoison_mock/https___osada.macgirvin.com_channel_mike.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://osada.macgirvin.com/.well-known/webfinger?resource=acct:mike@osada.macgirvin.com",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/mike@osada.macgirvin.com.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://social.heldscal.la/.well-known/webfinger?resource=https://social.heldscal.la/user/29191",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___social.heldscal.la_user_29191.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://pawoo.net/users/pekorino.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.atom")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://pawoo.net/.well-known/webfinger?resource=acct:https://pawoo.net/users/pekorino",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://social.stopwatchingus-heidelberg.de/api/statuses/user_timeline/18330.atom",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/atarifrosch_feed.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://social.stopwatchingus-heidelberg.de/.well-known/webfinger?resource=acct:https://social.stopwatchingus-heidelberg.de/user/18330",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/atarifrosch_webfinger.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://mamot.fr/users/Skruyb.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___mamot.fr_users_Skruyb.atom")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://mamot.fr/.well-known/webfinger?resource=acct:https://mamot.fr/users/Skruyb",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/skruyb@mamot.fr.atom")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://social.heldscal.la/.well-known/webfinger?resource=nonexistant@social.heldscal.la",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/nonexistant@social.heldscal.la.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://squeet.me/xrd/?uri=lain@squeet.me", _, _,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/lain_squeet.me_webfinger.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://mst3k.interlinked.me/users/luciferMysticus", _, _,
|
||||||
|
Accept: "application/activity+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/lucifermysticus.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://prismo.news/@mxb", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___prismo.news__mxb.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://hubzilla.example.org/channel/kaniini", _, _,
|
||||||
|
Accept: "application/activity+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/kaniini@hubzilla.example.org.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://niu.moe/users/rye", _, _, Accept: "application/activity+json") do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/rye.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://mastodon.example.org/users/admin/statuses/100787282858396771", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/http___mastodon.example.org_users_admin_status_1234.json"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://puckipedia.com/", _, _, Accept: "application/activity+json") do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/puckipedia.com.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://peertube.moe/accounts/7even", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/7even.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/peertube.moe-vid.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://baptiste.gelez.xyz/@/BaptisteGelez", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/baptiste.gelex.xyz-user.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/baptiste.gelex.xyz-article.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://mastodon.example.org/users/admin", _, _, Accept: "application/activity+json") do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/admin@mastdon.example.org.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://mastodon.example.org/@admin/99541947525187367", _, _,
|
||||||
|
Accept: "application/activity+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/mastodon-note-object.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://shitposter.club/notice/7369654", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/7369654.html")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://mstdn.io/users/mayuutann", _, _, Accept: "application/activity+json") do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/mayumayu.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://mstdn.io/users/mayuutann/statuses/99568293732299394", _, _,
|
||||||
|
Accept: "application/activity+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/mayumayupost.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://pleroma.soykaf.com/users/lain/feed.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/https___pleroma.soykaf.com_users_lain_feed.atom.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(url, _, _, Accept: "application/xrd+xml,application/jrd+json")
|
||||||
|
when url in [
|
||||||
|
"https://pleroma.soykaf.com/.well-known/webfinger?resource=acct:https://pleroma.soykaf.com/users/lain",
|
||||||
|
"https://pleroma.soykaf.com/.well-known/webfinger?resource=https://pleroma.soykaf.com/users/lain"
|
||||||
|
] do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___pleroma.soykaf.com_users_lain.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://shitposter.club/api/statuses/user_timeline/1.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/https___shitposter.club_api_statuses_user_timeline_1.atom.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/1",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___shitposter.club_user_1.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://shitposter.club/notice/2827873", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!("test/fixtures/httpoison_mock/https___shitposter.club_notice_2827873.html")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://shitposter.club/api/statuses/show/2827873.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/https___shitposter.club_api_statuses_show_2827873.atom.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://testing.pleroma.lol/objects/b319022a-4946-44c5-9de9-34801f95507b", _, _, _) do
|
||||||
|
{:ok, %Tesla.Env{status: 200}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://shitposter.club/api/statuses/user_timeline/5381.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/spc_5381.atom")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/5381",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/spc_5381_xrd.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://shitposter.club/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/shitposter.club_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://shitposter.club/api/statuses/show/7369654.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/7369654.atom")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://shitposter.club/notice/4027863", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/7369654.html")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://social.sakamoto.gq/users/eal/feed.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/sakamoto_eal_feed.atom")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://social.sakamoto.gq/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/social.sakamoto.gq_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://social.sakamoto.gq/.well-known/webfinger?resource=https://social.sakamoto.gq/users/eal",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/eal_sakamoto.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://social.sakamoto.gq/objects/0ccc1a2c-66b0-4305-b23a-7f7f2b040056", _, _,
|
||||||
|
Accept: "application/atom+xml"
|
||||||
|
) do
|
||||||
|
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/httpoison_mock/sakamoto.atom")}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://mastodon.social/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/mastodon.social_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://mastodon.social/.well-known/webfinger?resource=https://mastodon.social/users/lambadalambda",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/https___mastodon.social_users_lambadalambda.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://gs.example.org/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/gs.example.org_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"http://gs.example.org/.well-known/webfinger?resource=http://gs.example.org:4040/index.php/user/1",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/http___gs.example.org_4040_index.php_user_1.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://gs.example.org/index.php/api/statuses/user_timeline/1.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/http__gs.example.org_index.php_api_statuses_user_timeline_1.atom.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://social.heldscal.la/api/statuses/user_timeline/29191.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/https___social.heldscal.la_api_statuses_user_timeline_29191.atom.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://squeet.me/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{status: 200, body: File.read!("test/fixtures/httpoison_mock/squeet.me_host_meta")}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://squeet.me/xrd?uri=lain@squeet.me", _, _,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/lain_squeet.me_webfinger.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://social.heldscal.la/.well-known/webfinger?resource=shp@social.heldscal.la",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/shp@social.heldscal.la.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://framatube.org/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/framatube.org_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://framatube.org/main/xrd?uri=framasoft@framatube.org", _, _,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
headers: [{"content-type", "application/json"}],
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/framasoft@framatube.org.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://gnusocial.de/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/gnusocial.de_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://gnusocial.de/main/xrd?uri=winterdienst@gnusocial.de", _, _,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/winterdienst_webfinger.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://status.alpicola.com/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/status.alpicola.com_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://macgirvin.com/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/macgirvin.com_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://gerzilla.de/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/gerzilla.de_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://gerzilla.de/xrd/?uri=kaniini@gerzilla.de", _, _,
|
||||||
|
Accept: "application/xrd+xml,application/jrd+json"
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
headers: [{"content-type", "application/json"}],
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/kaniini@gerzilla.de.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://social.heldscal.la/api/statuses/user_timeline/23211.atom", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
File.read!(
|
||||||
|
"test/fixtures/httpoison_mock/https___social.heldscal.la_api_statuses_user_timeline_23211.atom.xml"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(
|
||||||
|
"https://social.heldscal.la/.well-known/webfinger?resource=https://social.heldscal.la/user/23211",
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_
|
||||||
|
) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/https___social.heldscal.la_user_23211.xml")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("http://social.heldscal.la/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/social.heldscal.la_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://social.heldscal.la/.well-known/host-meta", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/httpoison_mock/social.heldscal.la_host_meta")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://mastodon.social/users/lambadalambda.atom", _, _, _) do
|
||||||
|
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/lambadalambda.atom")}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://social.heldscal.la/user/23211", _, _, Accept: "application/activity+json") do
|
||||||
|
{:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(url, query, body, headers) do
|
||||||
|
{:error,
|
||||||
|
"Not implemented the mock response for get #{inspect(url)}, #{query}, #{inspect(body)}, #{
|
||||||
|
inspect(headers)
|
||||||
|
}"}
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST Requests
|
||||||
|
#
|
||||||
|
|
||||||
|
def post(url, query \\ [], body \\ [], headers \\ [])
|
||||||
|
|
||||||
|
def post("http://example.org/needs_refresh", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: ""
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def post(url, _query, _body, _headers) do
|
||||||
|
{:error, "Not implemented the mock response for post #{inspect(url)}"}
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,883 +0,0 @@
|
||||||
defmodule HTTPoisonMock do
|
|
||||||
alias HTTPoison.Response
|
|
||||||
|
|
||||||
def process_request_options(options), do: options
|
|
||||||
|
|
||||||
def get(url, body \\ [], headers \\ [])
|
|
||||||
|
|
||||||
def get("https://prismo.news/@mxb", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___prismo.news__mxb.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://osada.macgirvin.com/channel/mike", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!("test/fixtures/httpoison_mock/https___osada.macgirvin.com_channel_mike.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://osada.macgirvin.com/.well-known/webfinger?resource=acct:mike@osada.macgirvin.com",
|
|
||||||
_,
|
|
||||||
_
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/mike@osada.macgirvin.com.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://info.pleroma.site/activity.json", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https__info.pleroma.site_activity.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://info.pleroma.site/activity2.json", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https__info.pleroma.site_activity2.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://info.pleroma.site/activity3.json", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https__info.pleroma.site_activity3.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://info.pleroma.site/activity4.json", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https__info.pleroma.site_activity4.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://info.pleroma.site/actor.json", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___info.pleroma.site_actor.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://puckipedia.com/", [Accept: "application/activity+json"], _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/puckipedia.com.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://gerzilla.de/.well-known/webfinger?resource=acct:kaniini@gerzilla.de",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/kaniini@gerzilla.de.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://framatube.org/.well-known/webfinger?resource=acct:framasoft@framatube.org",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/framasoft@framatube.org.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://gnusocial.de/.well-known/webfinger?resource=acct:winterdienst@gnusocial.de",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/winterdienst_webfinger.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.heldscal.la/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "nonexistant@social.heldscal.la"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 500,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/nonexistant@social.heldscal.la.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.heldscal.la/.well-known/webfinger?resource=shp@social.heldscal.la",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/shp@social.heldscal.la.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.heldscal.la/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "shp@social.heldscal.la"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/shp@social.heldscal.la.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.heldscal.la/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://social.heldscal.la/user/23211"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___social.heldscal.la_user_23211.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.heldscal.la/.well-known/webfinger?resource=https://social.heldscal.la/user/23211",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___social.heldscal.la_user_23211.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.heldscal.la/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://social.heldscal.la/user/29191"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___social.heldscal.la_user_29191.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.heldscal.la/.well-known/webfinger?resource=https://social.heldscal.la/user/29191",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___social.heldscal.la_user_29191.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://mastodon.social/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://mastodon.social/users/lambadalambda"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___mastodon.social_users_lambadalambda.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://mastodon.social/.well-known/webfinger?resource=https://mastodon.social/users/lambadalambda",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___mastodon.social_users_lambadalambda.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://shitposter.club/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://shitposter.club/user/1"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___shitposter.club_user_1.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/1",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___shitposter.club_user_1.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/5381",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/spc_5381_xrd.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"http://gs.example.org/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "http://gs.example.org:4040/index.php/user/1"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/http___gs.example.org_4040_index.php_user_1.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"http://gs.example.org/.well-known/webfinger?resource=http://gs.example.org:4040/index.php/user/1",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/http___gs.example.org_4040_index.php_user_1.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.stopwatchingus-heidelberg.de/.well-known/webfinger?resource=https://social.stopwatchingus-heidelberg.de/user/18330",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/atarifrosch_webfinger.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://pleroma.soykaf.com/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://pleroma.soykaf.com/users/lain"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___pleroma.soykaf.com_users_lain.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://pleroma.soykaf.com/.well-known/webfinger?resource=https://pleroma.soykaf.com/users/lain",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___pleroma.soykaf.com_users_lain.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://social.heldscal.la/api/statuses/user_timeline/29191.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___social.heldscal.la_api_statuses_user_timeline_29191.atom.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://shitposter.club/api/statuses/user_timeline/5381.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/spc_5381.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://social.heldscal.la/api/statuses/user_timeline/23211.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___social.heldscal.la_api_statuses_user_timeline_23211.atom.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://mastodon.social/users/lambadalambda.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___mastodon.social_users_lambadalambda.atom"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.stopwatchingus-heidelberg.de/api/statuses/user_timeline/18330.atom",
|
|
||||||
_body,
|
|
||||||
_headers
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/atarifrosch_feed.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://pleroma.soykaf.com/users/lain/feed.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___pleroma.soykaf.com_users_lain_feed.atom.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://social.sakamoto.gq/users/eal/feed.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/sakamoto_eal_feed.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://gs.example.org/index.php/api/statuses/user_timeline/1.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/http__gs.example.org_index.php_api_statuses_user_timeline_1.atom.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://shitposter.club/notice/2827873", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!("test/fixtures/httpoison_mock/https___shitposter.club_notice_2827873.html")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://shitposter.club/api/statuses/show/2827873.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___shitposter.club_api_statuses_show_2827873.atom.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://shitposter.club/api/statuses/user_timeline/1.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/https___shitposter.club_api_statuses_user_timeline_1.atom.xml"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def post(
|
|
||||||
"https://social.heldscal.la/main/push/hub",
|
|
||||||
{:form, _data},
|
|
||||||
"Content-type": "application/x-www-form-urlencoded"
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 202
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://mastodon.example.org/users/admin/statuses/100787282858396771", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!(
|
|
||||||
"test/fixtures/httpoison_mock/http___mastodon.example.org_users_admin_status_1234.json"
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://pawoo.net/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://pawoo.net/users/pekorino"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://pawoo.net/.well-known/webfinger?resource=https://pawoo.net/users/pekorino",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://pawoo.net/users/pekorino.atom", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___pawoo.net_users_pekorino.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://mamot.fr/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://mamot.fr/users/Skruyb"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/skruyb@mamot.fr.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://mamot.fr/.well-known/webfinger?resource=https://mamot.fr/users/Skruyb",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/skruyb@mamot.fr.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.sakamoto.gq/.well-known/webfinger",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
params: [resource: "https://social.sakamoto.gq/users/eal"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/eal_sakamoto.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.sakamoto.gq/.well-known/webfinger?resource=https://social.sakamoto.gq/users/eal",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/eal_sakamoto.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://pleroma.soykaf.com/.well-known/webfinger?resource=https://pleroma.soykaf.com/users/shp",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/shp@pleroma.soykaf.com.webfigner")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://squeet.me/xrd/?uri=lain@squeet.me",
|
|
||||||
[Accept: "application/xrd+xml,application/jrd+json"],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/lain_squeet.me_webfinger.xml")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://mamot.fr/users/Skruyb.atom", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/https___mamot.fr_users_Skruyb.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://social.sakamoto.gq/objects/0ccc1a2c-66b0-4305-b23a-7f7f2b040056",
|
|
||||||
[Accept: "application/atom+xml"],
|
|
||||||
_
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/sakamoto.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://pleroma.soykaf.com/users/shp/feed.atom", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/shp@pleroma.soykaf.com.feed")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://social.heldscal.la/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/social.heldscal.la_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://status.alpicola.com/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/status.alpicola.com_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://macgirvin.com/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/macgirvin.com_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://mastodon.social/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/mastodon.social_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://shitposter.club/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/shitposter.club_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://pleroma.soykaf.com/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/pleroma.soykaf.com_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://social.sakamoto.gq/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/social.sakamoto.gq_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://gs.example.org/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/gs.example.org_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://pawoo.net/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/pawoo.net_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://mamot.fr/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/mamot.fr_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://mastodon.xyz/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/mastodon.xyz_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://social.wxcafe.net/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/social.wxcafe.net_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://squeet.me/.well-known/host-meta", [], follow_redirect: true) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/squeet.me_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"http://social.stopwatchingus-heidelberg.de/.well-known/host-meta",
|
|
||||||
[],
|
|
||||||
follow_redirect: true
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body:
|
|
||||||
File.read!("test/fixtures/httpoison_mock/social.stopwatchingus-heidelberg.de_host_meta")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("http://mastodon.example.org/users/admin", [Accept: "application/activity+json"], _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/admin@mastdon.example.org.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://hubzilla.example.org/channel/kaniini",
|
|
||||||
[Accept: "application/activity+json"],
|
|
||||||
_
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/kaniini@hubzilla.example.org.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://masto.quad.moe/users/_HellPie", [Accept: "application/activity+json"], _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/hellpie.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://niu.moe/users/rye", [Accept: "application/activity+json"], _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/rye.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://n1u.moe/users/rye", [Accept: "application/activity+json"], _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/rye.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://mst3k.interlinked.me/users/luciferMysticus",
|
|
||||||
[Accept: "application/activity+json"],
|
|
||||||
_
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/lucifermysticus.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://mstdn.io/users/mayuutann", [Accept: "application/activity+json"], _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/mayumayu.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"http://mastodon.example.org/@admin/99541947525187367",
|
|
||||||
[Accept: "application/activity+json"],
|
|
||||||
_
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/mastodon-note-object.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(
|
|
||||||
"https://mstdn.io/users/mayuutann/statuses/99568293732299394",
|
|
||||||
[Accept: "application/activity+json"],
|
|
||||||
_
|
|
||||||
) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/mayumayupost.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://shitposter.club/notice/7369654", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/7369654.html")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://shitposter.club/api/statuses/show/7369654.atom", _body, _headers) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/7369654.atom")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://baptiste.gelez.xyz/~/PlumeDevelopment/this-month-in-plume-june-2018/", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/baptiste.gelex.xyz-article.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://baptiste.gelez.xyz/@/BaptisteGelez", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/baptiste.gelex.xyz-user.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/peertube.moe-vid.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get("https://peertube.moe/accounts/7even", _, _) do
|
|
||||||
{:ok,
|
|
||||||
%Response{
|
|
||||||
status_code: 200,
|
|
||||||
body: File.read!("test/fixtures/httpoison_mock/7even.json")
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(url, body, headers) do
|
|
||||||
{:error,
|
|
||||||
"Not implemented the mock response for get #{inspect(url)}, #{inspect(body)}, #{
|
|
||||||
inspect(headers)
|
|
||||||
}"}
|
|
||||||
end
|
|
||||||
|
|
||||||
def post(url, _body, _headers) do
|
|
||||||
{:error, "Not implemented the mock response for post #{inspect(url)}"}
|
|
||||||
end
|
|
||||||
|
|
||||||
def post(url, _body, _headers, _options) do
|
|
||||||
{:error, "Not implemented the mock response for post #{inspect(url)}"}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -9,6 +9,11 @@ defmodule Pleroma.UserTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "ap_id returns the activity pub id for the user" do
|
test "ap_id returns the activity pub id for the user" do
|
||||||
user = UserBuilder.build()
|
user = UserBuilder.build()
|
||||||
|
|
||||||
|
@ -34,14 +39,14 @@ test "follow takes a user and another user" do
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
|
|
||||||
followed = User.get_by_ap_id(followed.ap_id)
|
followed = User.get_by_ap_id(followed.ap_id)
|
||||||
assert followed.info["follower_count"] == 1
|
assert followed.info.follower_count == 1
|
||||||
|
|
||||||
assert User.ap_followers(followed) in user.following
|
assert User.ap_followers(followed) in user.following
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can't follow a deactivated users" do
|
test "can't follow a deactivated users" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
followed = insert(:user, info: %{"deactivated" => true})
|
followed = insert(:user, info: %{deactivated: true})
|
||||||
|
|
||||||
{:error, _} = User.follow(user, followed)
|
{:error, _} = User.follow(user, followed)
|
||||||
end
|
end
|
||||||
|
@ -56,8 +61,8 @@ test "can't follow a user who blocked us" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "local users do not automatically follow local locked accounts" do
|
test "local users do not automatically follow local locked accounts" do
|
||||||
follower = insert(:user, info: %{"locked" => true})
|
follower = insert(:user, info: %{locked: true})
|
||||||
followed = insert(:user, info: %{"locked" => true})
|
followed = insert(:user, info: %{locked: true})
|
||||||
|
|
||||||
{:ok, follower} = User.maybe_direct_follow(follower, followed)
|
{:ok, follower} = User.maybe_direct_follow(follower, followed)
|
||||||
|
|
||||||
|
@ -144,6 +149,18 @@ test "it sets the password_hash, ap_id and following fields" do
|
||||||
|
|
||||||
assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
|
assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it ensures info is not nil" do
|
||||||
|
changeset = User.register_changeset(%User{}, @full_user_data)
|
||||||
|
|
||||||
|
assert changeset.valid?
|
||||||
|
|
||||||
|
{:ok, user} =
|
||||||
|
changeset
|
||||||
|
|> Repo.insert()
|
||||||
|
|
||||||
|
refute is_nil(user.info)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "fetching a user from nickname or trying to build one" do
|
describe "fetching a user from nickname or trying to build one" do
|
||||||
|
@ -185,12 +202,14 @@ test "updates an existing user, if stale" do
|
||||||
local: false,
|
local: false,
|
||||||
nickname: "admin@mastodon.example.org",
|
nickname: "admin@mastodon.example.org",
|
||||||
ap_id: "http://mastodon.example.org/users/admin",
|
ap_id: "http://mastodon.example.org/users/admin",
|
||||||
last_refreshed_at: a_week_ago
|
last_refreshed_at: a_week_ago,
|
||||||
|
info: %{}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert orig_user.last_refreshed_at == a_week_ago
|
assert orig_user.last_refreshed_at == a_week_ago
|
||||||
|
|
||||||
user = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
|
user = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
|
||||||
|
assert user.info.source_data["endpoints"]
|
||||||
|
|
||||||
refute user.last_refreshed_at == orig_user.last_refreshed_at
|
refute user.last_refreshed_at == orig_user.last_refreshed_at
|
||||||
end
|
end
|
||||||
|
@ -311,45 +330,45 @@ test "it sets the info->note_count property" do
|
||||||
|
|
||||||
user = User.get_by_ap_id(note.data["actor"])
|
user = User.get_by_ap_id(note.data["actor"])
|
||||||
|
|
||||||
assert user.info["note_count"] == nil
|
assert user.info.note_count == 0
|
||||||
|
|
||||||
{:ok, user} = User.update_note_count(user)
|
{:ok, user} = User.update_note_count(user)
|
||||||
|
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it increases the info->note_count property" do
|
test "it increases the info->note_count property" do
|
||||||
note = insert(:note)
|
note = insert(:note)
|
||||||
user = User.get_by_ap_id(note.data["actor"])
|
user = User.get_by_ap_id(note.data["actor"])
|
||||||
|
|
||||||
assert user.info["note_count"] == nil
|
assert user.info.note_count == 0
|
||||||
|
|
||||||
{:ok, user} = User.increase_note_count(user)
|
{:ok, user} = User.increase_note_count(user)
|
||||||
|
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
|
|
||||||
{:ok, user} = User.increase_note_count(user)
|
{:ok, user} = User.increase_note_count(user)
|
||||||
|
|
||||||
assert user.info["note_count"] == 2
|
assert user.info.note_count == 2
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it decreases the info->note_count property" do
|
test "it decreases the info->note_count property" do
|
||||||
note = insert(:note)
|
note = insert(:note)
|
||||||
user = User.get_by_ap_id(note.data["actor"])
|
user = User.get_by_ap_id(note.data["actor"])
|
||||||
|
|
||||||
assert user.info["note_count"] == nil
|
assert user.info.note_count == 0
|
||||||
|
|
||||||
{:ok, user} = User.increase_note_count(user)
|
{:ok, user} = User.increase_note_count(user)
|
||||||
|
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
|
|
||||||
{:ok, user} = User.decrease_note_count(user)
|
{:ok, user} = User.decrease_note_count(user)
|
||||||
|
|
||||||
assert user.info["note_count"] == 0
|
assert user.info.note_count == 0
|
||||||
|
|
||||||
{:ok, user} = User.decrease_note_count(user)
|
{:ok, user} = User.decrease_note_count(user)
|
||||||
|
|
||||||
assert user.info["note_count"] == 0
|
assert user.info.note_count == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it sets the info->follower_count property" do
|
test "it sets the info->follower_count property" do
|
||||||
|
@ -358,11 +377,11 @@ test "it sets the info->follower_count property" do
|
||||||
|
|
||||||
User.follow(follower, user)
|
User.follow(follower, user)
|
||||||
|
|
||||||
assert user.info["follower_count"] == nil
|
assert user.info.follower_count == 0
|
||||||
|
|
||||||
{:ok, user} = User.update_follower_count(user)
|
{:ok, user} = User.update_follower_count(user)
|
||||||
|
|
||||||
assert user.info["follower_count"] == 1
|
assert user.info.follower_count == 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -489,11 +508,11 @@ test "get recipients from activity" do
|
||||||
|
|
||||||
test ".deactivate can de-activate then re-activate a user" do
|
test ".deactivate can de-activate then re-activate a user" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
assert false == !!user.info["deactivated"]
|
assert false == user.info.deactivated
|
||||||
{:ok, user} = User.deactivate(user)
|
{:ok, user} = User.deactivate(user)
|
||||||
assert true == user.info["deactivated"]
|
assert true == user.info.deactivated
|
||||||
{:ok, user} = User.deactivate(user, false)
|
{:ok, user} = User.deactivate(user, false)
|
||||||
assert false == !!user.info["deactivated"]
|
assert false == user.info.deactivated
|
||||||
end
|
end
|
||||||
|
|
||||||
test ".delete deactivates a user, all follow relationships and all create activities" do
|
test ".delete deactivates a user, all follow relationships and all create activities" do
|
||||||
|
@ -517,7 +536,7 @@ test ".delete deactivates a user, all follow relationships and all create activi
|
||||||
follower = Repo.get(User, follower.id)
|
follower = Repo.get(User, follower.id)
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
|
|
||||||
assert user.info["deactivated"]
|
assert user.info.deactivated
|
||||||
|
|
||||||
refute User.following?(user, followed)
|
refute User.following?(user, followed)
|
||||||
refute User.following?(followed, follower)
|
refute User.following?(followed, follower)
|
||||||
|
@ -546,7 +565,7 @@ test "html_filter_policy returns nil when rich-text is enabled" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
|
test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
|
||||||
user = insert(:user, %{info: %{"no_rich_text" => true}})
|
user = insert(:user, %{info: %{no_rich_text: true}})
|
||||||
|
|
||||||
assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
|
assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||||
alias Pleroma.{Repo, User}
|
alias Pleroma.{Repo, User}
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
describe "/relay" do
|
describe "/relay" do
|
||||||
test "with the relay active, it returns the relay user", %{conn: conn} do
|
test "with the relay active, it returns the relay user", %{conn: conn} do
|
||||||
res =
|
res =
|
||||||
|
|
|
@ -7,6 +7,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
||||||
alias Pleroma.Builders.ActivityBuilder
|
alias Pleroma.Builders.ActivityBuilder
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
describe "building a user from his ap id" do
|
describe "building a user from his ap id" do
|
||||||
test "it returns a user" do
|
test "it returns a user" do
|
||||||
|
@ -14,8 +20,8 @@ test "it returns a user" do
|
||||||
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
||||||
assert user.ap_id == user_id
|
assert user.ap_id == user_id
|
||||||
assert user.nickname == "admin@mastodon.example.org"
|
assert user.nickname == "admin@mastodon.example.org"
|
||||||
assert user.info["source_data"]
|
assert user.info.source_data
|
||||||
assert user.info["ap_enabled"]
|
assert user.info.ap_enabled
|
||||||
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
|
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,11 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
describe "handle_incoming" do
|
describe "handle_incoming" do
|
||||||
test "it ignores an incoming notice if we already have it" do
|
test "it ignores an incoming notice if we already have it" do
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
|
@ -92,7 +97,7 @@ test "it works for incoming notices" do
|
||||||
|
|
||||||
user = User.get_by_ap_id(object["actor"])
|
user = User.get_by_ap_id(object["actor"])
|
||||||
|
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it works for incoming notices with hashtags" do
|
test "it works for incoming notices with hashtags" do
|
||||||
|
@ -307,7 +312,7 @@ test "it works for incoming update activities" do
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
assert user.info["banner"]["url"] == [
|
assert user.info.banner["url"] == [
|
||||||
%{
|
%{
|
||||||
"href" =>
|
"href" =>
|
||||||
"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
||||||
|
@ -337,7 +342,7 @@ test "it works for incoming update activities which lock the account" do
|
||||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
|
||||||
|
|
||||||
user = User.get_cached_by_ap_id(data["actor"])
|
user = User.get_cached_by_ap_id(data["actor"])
|
||||||
assert user.info["locked"] == true
|
assert user.info.locked == true
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it works for incoming deletes" do
|
test "it works for incoming deletes" do
|
||||||
|
@ -543,7 +548,7 @@ test "it works for incoming accepts which were pre-accepted" do
|
||||||
|
|
||||||
test "it works for incoming accepts which were orphaned" do
|
test "it works for incoming accepts which were orphaned" do
|
||||||
follower = insert(:user)
|
follower = insert(:user)
|
||||||
followed = insert(:user, %{info: %{"locked" => true}})
|
followed = insert(:user, %{info: %User.Info{locked: true}})
|
||||||
|
|
||||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||||
|
|
||||||
|
@ -565,7 +570,7 @@ test "it works for incoming accepts which were orphaned" do
|
||||||
|
|
||||||
test "it works for incoming accepts which are referenced by IRI only" do
|
test "it works for incoming accepts which are referenced by IRI only" do
|
||||||
follower = insert(:user)
|
follower = insert(:user)
|
||||||
followed = insert(:user, %{info: %{"locked" => true}})
|
followed = insert(:user, %{info: %User.Info{locked: true}})
|
||||||
|
|
||||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||||
|
|
||||||
|
@ -585,7 +590,7 @@ test "it works for incoming accepts which are referenced by IRI only" do
|
||||||
|
|
||||||
test "it fails for incoming accepts which cannot be correlated" do
|
test "it fails for incoming accepts which cannot be correlated" do
|
||||||
follower = insert(:user)
|
follower = insert(:user)
|
||||||
followed = insert(:user, %{info: %{"locked" => true}})
|
followed = insert(:user, %{info: %User.Info{locked: true}})
|
||||||
|
|
||||||
accept_data =
|
accept_data =
|
||||||
File.read!("test/fixtures/mastodon-accept-activity.json")
|
File.read!("test/fixtures/mastodon-accept-activity.json")
|
||||||
|
@ -604,7 +609,7 @@ test "it fails for incoming accepts which cannot be correlated" do
|
||||||
|
|
||||||
test "it fails for incoming rejects which cannot be correlated" do
|
test "it fails for incoming rejects which cannot be correlated" do
|
||||||
follower = insert(:user)
|
follower = insert(:user)
|
||||||
followed = insert(:user, %{info: %{"locked" => true}})
|
followed = insert(:user, %{info: %User.Info{locked: true}})
|
||||||
|
|
||||||
accept_data =
|
accept_data =
|
||||||
File.read!("test/fixtures/mastodon-reject-activity.json")
|
File.read!("test/fixtures/mastodon-reject-activity.json")
|
||||||
|
@ -623,7 +628,7 @@ test "it fails for incoming rejects which cannot be correlated" do
|
||||||
|
|
||||||
test "it works for incoming rejects which are orphaned" do
|
test "it works for incoming rejects which are orphaned" do
|
||||||
follower = insert(:user)
|
follower = insert(:user)
|
||||||
followed = insert(:user, %{info: %{"locked" => true}})
|
followed = insert(:user, %{info: %User.Info{locked: true}})
|
||||||
|
|
||||||
{:ok, follower} = User.follow(follower, followed)
|
{:ok, follower} = User.follow(follower, followed)
|
||||||
{:ok, _follow_activity} = ActivityPub.follow(follower, followed)
|
{:ok, _follow_activity} = ActivityPub.follow(follower, followed)
|
||||||
|
@ -648,7 +653,7 @@ test "it works for incoming rejects which are orphaned" do
|
||||||
|
|
||||||
test "it works for incoming rejects which are referenced by IRI only" do
|
test "it works for incoming rejects which are referenced by IRI only" do
|
||||||
follower = insert(:user)
|
follower = insert(:user)
|
||||||
followed = insert(:user, %{info: %{"locked" => true}})
|
followed = insert(:user, %{info: %User.Info{locked: true}})
|
||||||
|
|
||||||
{:ok, follower} = User.follow(follower, followed)
|
{:ok, follower} = User.follow(follower, followed)
|
||||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||||
|
@ -815,18 +820,18 @@ test "it upgrades a user to activitypub" do
|
||||||
assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
|
assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
|
||||||
|
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
|
|
||||||
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
|
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
|
||||||
assert user.info["ap_enabled"]
|
assert user.info.ap_enabled
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
assert user.follower_address == "https://niu.moe/users/rye/followers"
|
assert user.follower_address == "https://niu.moe/users/rye/followers"
|
||||||
|
|
||||||
# Wait for the background task
|
# Wait for the background task
|
||||||
:timer.sleep(1000)
|
:timer.sleep(1000)
|
||||||
|
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
|
|
||||||
activity = Repo.get(Activity, activity.id)
|
activity = Repo.get(Activity, activity.id)
|
||||||
assert user.follower_address in activity.recipients
|
assert user.follower_address in activity.recipients
|
||||||
|
@ -847,7 +852,7 @@ test "it upgrades a user to activitypub" do
|
||||||
"https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
"https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
} = user.info["banner"]
|
} = user.info.banner
|
||||||
|
|
||||||
refute "..." in activity.recipients
|
refute "..." in activity.recipients
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
||||||
|
|
||||||
describe "/api/pleroma/admin/user" do
|
describe "/api/pleroma/admin/user" do
|
||||||
test "Delete" do
|
test "Delete" do
|
||||||
admin = insert(:user, info: %{"is_admin" => true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
@ -21,7 +21,7 @@ test "Delete" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "Create" do
|
test "Create" do
|
||||||
admin = insert(:user, info: %{"is_admin" => true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
@ -39,7 +39,7 @@ test "Create" do
|
||||||
|
|
||||||
describe "/api/pleroma/admin/permission_group" do
|
describe "/api/pleroma/admin/permission_group" do
|
||||||
test "GET is giving user_info" do
|
test "GET is giving user_info" do
|
||||||
admin = insert(:user, info: %{"is_admin" => true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
@ -47,33 +47,30 @@ test "GET is giving user_info" do
|
||||||
|> put_req_header("accept", "application/json")
|
|> put_req_header("accept", "application/json")
|
||||||
|> get("/api/pleroma/admin/permission_group/#{admin.nickname}")
|
|> get("/api/pleroma/admin/permission_group/#{admin.nickname}")
|
||||||
|
|
||||||
assert json_response(conn, 200) == admin.info
|
assert json_response(conn, 200) == %{
|
||||||
|
"is_admin" => true,
|
||||||
|
"is_moderator" => false
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "/:right POST, can add to a permission group" do
|
test "/:right POST, can add to a permission group" do
|
||||||
admin = insert(:user, info: %{"is_admin" => true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
user_info =
|
|
||||||
user.info
|
|
||||||
|> Map.put("is_admin", true)
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, admin)
|
|> assign(:user, admin)
|
||||||
|> put_req_header("accept", "application/json")
|
|> put_req_header("accept", "application/json")
|
||||||
|> post("/api/pleroma/admin/permission_group/#{user.nickname}/admin")
|
|> post("/api/pleroma/admin/permission_group/#{user.nickname}/admin")
|
||||||
|
|
||||||
assert json_response(conn, 200) == user_info
|
assert json_response(conn, 200) == %{
|
||||||
|
"is_admin" => true
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "/:right DELETE, can remove from a permission group" do
|
test "/:right DELETE, can remove from a permission group" do
|
||||||
admin = insert(:user, info: %{"is_admin" => true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
user = insert(:user, info: %{"is_admin" => true})
|
user = insert(:user, info: %{is_admin: true})
|
||||||
|
|
||||||
user_info =
|
|
||||||
user.info
|
|
||||||
|> Map.put("is_admin", false)
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
@ -81,12 +78,14 @@ test "/:right DELETE, can remove from a permission group" do
|
||||||
|> put_req_header("accept", "application/json")
|
|> put_req_header("accept", "application/json")
|
||||||
|> delete("/api/pleroma/admin/permission_group/#{user.nickname}/admin")
|
|> delete("/api/pleroma/admin/permission_group/#{user.nickname}/admin")
|
||||||
|
|
||||||
assert json_response(conn, 200) == user_info
|
assert json_response(conn, 200) == %{
|
||||||
|
"is_admin" => false
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "/api/pleroma/admin/invite_token" do
|
test "/api/pleroma/admin/invite_token" do
|
||||||
admin = insert(:user, info: %{"is_admin" => true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
@ -98,8 +97,8 @@ test "/api/pleroma/admin/invite_token" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "/api/pleroma/admin/password_reset" do
|
test "/api/pleroma/admin/password_reset" do
|
||||||
admin = insert(:user, info: %{"is_admin" => true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
user = insert(:user, info: %{"is_admin" => true})
|
user = insert(:user)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
|
|
@ -17,7 +17,7 @@ test "it adds emoji when updating profiles" do
|
||||||
|
|
||||||
CommonAPI.update(user)
|
CommonAPI.update(user)
|
||||||
user = User.get_cached_by_ap_id(user.ap_id)
|
user = User.get_cached_by_ap_id(user.ap_id)
|
||||||
[karjalanpiirakka] = user.info["source_data"]["tag"]
|
[karjalanpiirakka] = user.info.source_data["tag"]
|
||||||
|
|
||||||
assert karjalanpiirakka["name"] == ":karjalanpiirakka:"
|
assert karjalanpiirakka["name"] == ":karjalanpiirakka:"
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,11 @@ defmodule Pleroma.Web.FederatorTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import Mock
|
import Mock
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "enqueues an element according to priority" do
|
test "enqueues an element according to priority" do
|
||||||
queue = [%{item: 1, priority: 2}]
|
queue = [%{item: 1, priority: 2}]
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,12 @@ defmodule Pleroma.Web.HTTPSignaturesTest do
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
alias Pleroma.Web.HTTPSignatures
|
alias Pleroma.Web.HTTPSignatures
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
@private_key hd(:public_key.pem_decode(File.read!("test/web/http_sigs/priv.key")))
|
@private_key hd(:public_key.pem_decode(File.read!("test/web/http_sigs/priv.key")))
|
||||||
|> :public_key.pem_entry_decode()
|
|> :public_key.pem_entry_decode()
|
||||||
|
|
|
@ -17,7 +17,7 @@ test "Represent a user account" do
|
||||||
|
|
||||||
user =
|
user =
|
||||||
insert(:user, %{
|
insert(:user, %{
|
||||||
info: %{"note_count" => 5, "follower_count" => 3, "source_data" => source_data},
|
info: %{note_count: 5, follower_count: 3, source_data: source_data},
|
||||||
nickname: "shp@shitposter.club",
|
nickname: "shp@shitposter.club",
|
||||||
name: ":karjalanpiirakka: shp",
|
name: ":karjalanpiirakka: shp",
|
||||||
bio: "<script src=\"invalid-html\"></script><span>valid html</span>",
|
bio: "<script src=\"invalid-html\"></script><span>valid html</span>",
|
||||||
|
@ -63,7 +63,7 @@ test "Represent a user account" do
|
||||||
test "Represent a Service(bot) account" do
|
test "Represent a Service(bot) account" do
|
||||||
user =
|
user =
|
||||||
insert(:user, %{
|
insert(:user, %{
|
||||||
info: %{"note_count" => 5, "follower_count" => 3, "source_data" => %{"type" => "Service"}},
|
info: %{note_count: 5, follower_count: 3, source_data: %{"type" => "Service"}},
|
||||||
nickname: "shp@shitposter.club",
|
nickname: "shp@shitposter.club",
|
||||||
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,6 +8,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import ExUnit.CaptureLog
|
import ExUnit.CaptureLog
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "the home timeline", %{conn: conn} do
|
test "the home timeline", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -252,7 +258,7 @@ test "verify_credentials", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "verify_credentials default scope unlisted", %{conn: conn} do
|
test "verify_credentials default scope unlisted", %{conn: conn} do
|
||||||
user = insert(:user, %{info: %{"default_scope" => "unlisted"}})
|
user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "unlisted"}})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|
@ -845,7 +851,7 @@ test "returns the relationships for the current user", %{conn: conn} do
|
||||||
|
|
||||||
describe "locked accounts" do
|
describe "locked accounts" do
|
||||||
test "/api/v1/follow_requests works" do
|
test "/api/v1/follow_requests works" do
|
||||||
user = insert(:user, %{info: %{"locked" => true}})
|
user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
||||||
{:ok, activity} = ActivityPub.follow(other_user, user)
|
{:ok, activity} = ActivityPub.follow(other_user, user)
|
||||||
|
@ -865,7 +871,7 @@ test "/api/v1/follow_requests works" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "/api/v1/follow_requests/:id/authorize works" do
|
test "/api/v1/follow_requests/:id/authorize works" do
|
||||||
user = insert(:user, %{info: %{"locked" => true}})
|
user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
||||||
{:ok, activity} = ActivityPub.follow(other_user, user)
|
{:ok, activity} = ActivityPub.follow(other_user, user)
|
||||||
|
@ -890,7 +896,7 @@ test "/api/v1/follow_requests/:id/authorize works" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "verify_credentials", %{conn: conn} do
|
test "verify_credentials", %{conn: conn} do
|
||||||
user = insert(:user, %{info: %{"default_scope" => "private"}})
|
user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "private"}})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|
@ -902,7 +908,7 @@ test "verify_credentials", %{conn: conn} do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "/api/v1/follow_requests/:id/reject works" do
|
test "/api/v1/follow_requests/:id/reject works" do
|
||||||
user = insert(:user, %{info: %{"locked" => true}})
|
user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
||||||
{:ok, activity} = ActivityPub.follow(other_user, user)
|
{:ok, activity} = ActivityPub.follow(other_user, user)
|
||||||
|
@ -1105,7 +1111,7 @@ test "blocking / unblocking a domain", %{conn: conn} do
|
||||||
refute User.blocks?(user, other_user)
|
refute User.blocks?(user, other_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "getting a list of domain blocks" do
|
test "getting a list of domain blocks", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
{:ok, user} = User.block_domain(user, "bad.site")
|
{:ok, user} = User.block_domain(user, "bad.site")
|
||||||
|
@ -1253,14 +1259,33 @@ test "returns the favorites of a user", %{conn: conn} do
|
||||||
describe "updating credentials" do
|
describe "updating credentials" do
|
||||||
test "updates the user's bio", %{conn: conn} do
|
test "updates the user's bio", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
user2 = insert(:user)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> patch("/api/v1/accounts/update_credentials", %{"note" => "I drink #cofe"})
|
|> patch("/api/v1/accounts/update_credentials", %{
|
||||||
|
"note" => "I drink #cofe with @#{user2.nickname}"
|
||||||
|
})
|
||||||
|
|
||||||
assert user = json_response(conn, 200)
|
assert user = json_response(conn, 200)
|
||||||
assert user["note"] == "I drink #cofe"
|
|
||||||
|
assert user["note"] ==
|
||||||
|
"I drink <a href=\"http://localhost:4001/tag/cofe\">#cofe</a> with <span><a href=\"#{
|
||||||
|
user2.ap_id
|
||||||
|
}\">@<span>#{user2.nickname}</span></a></span>"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "updates the user's locking status", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> patch("/api/v1/accounts/update_credentials", %{locked: "true"})
|
||||||
|
|
||||||
|
assert user = json_response(conn, 200)
|
||||||
|
assert user["locked"] == true
|
||||||
end
|
end
|
||||||
|
|
||||||
test "updates the user's name", %{conn: conn} do
|
test "updates the user's name", %{conn: conn} do
|
||||||
|
@ -1289,8 +1314,8 @@ test "updates the user's avatar", %{conn: conn} do
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
|
|> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
|
||||||
|
|
||||||
assert user = json_response(conn, 200)
|
assert user_response = json_response(conn, 200)
|
||||||
assert user["avatar"] != "https://placehold.it/48x48"
|
assert user_response["avatar"] != User.avatar_url(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "updates the user's banner", %{conn: conn} do
|
test "updates the user's banner", %{conn: conn} do
|
||||||
|
@ -1307,8 +1332,8 @@ test "updates the user's banner", %{conn: conn} do
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
|
|> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
|
||||||
|
|
||||||
assert user = json_response(conn, 200)
|
assert user_response = json_response(conn, 200)
|
||||||
assert user["header"] != "https://placehold.it/700x335"
|
assert user_response["header"] != User.banner_url(user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
||||||
alias Pleroma.Web.OStatus
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "a note with null content" do
|
test "a note with null content" do
|
||||||
note = insert(:note_activity)
|
note = insert(:note_activity)
|
||||||
|
|
|
@ -4,7 +4,7 @@ defmodule Pleroma.Web.NodeInfoTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
test "nodeinfo shows staff accounts", %{conn: conn} do
|
test "nodeinfo shows staff accounts", %{conn: conn} do
|
||||||
user = insert(:user, %{local: true, info: %{"is_moderator" => true}})
|
user = insert(:user, %{local: true, info: %{is_moderator: true}})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|
@ -15,7 +15,7 @@ test "nodeinfo shows staff accounts", %{conn: conn} do
|
||||||
assert user.ap_id in result["metadata"]["staffAccounts"]
|
assert user.ap_id in result["metadata"]["staffAccounts"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns 404 when federation is disabled" do
|
test "returns 404 when federation is disabled", %{conn: conn} do
|
||||||
instance =
|
instance =
|
||||||
Application.get_env(:pleroma, :instance)
|
Application.get_env(:pleroma, :instance)
|
||||||
|> Keyword.put(:federating, false)
|
|> Keyword.put(:federating, false)
|
||||||
|
@ -37,7 +37,7 @@ test "returns 404 when federation is disabled" do
|
||||||
Application.put_env(:pleroma, :instance, instance)
|
Application.put_env(:pleroma, :instance, instance)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns 200 when federation is enabled" do
|
test "returns 200 when federation is enabled", %{conn: conn} do
|
||||||
conn
|
conn
|
||||||
|> get("/.well-known/nodeinfo")
|
|> get("/.well-known/nodeinfo")
|
||||||
|> json_response(200)
|
|> json_response(200)
|
||||||
|
|
|
@ -7,6 +7,12 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenterTest do
|
||||||
alias Pleroma.Web.OStatus
|
alias Pleroma.Web.OStatus
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "an external note activity" do
|
test "an external note activity" do
|
||||||
incoming = File.read!("test/fixtures/mastodon-note-cw.xml")
|
incoming = File.read!("test/fixtures/mastodon-note-cw.xml")
|
||||||
|
|
|
@ -5,6 +5,11 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.OStatus.ActivityRepresenter
|
alias Pleroma.Web.OStatus.ActivityRepresenter
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "decodes a salmon", %{conn: conn} do
|
test "decodes a salmon", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
salmon = File.read!("test/fixtures/salmon.xml")
|
salmon = File.read!("test/fixtures/salmon.xml")
|
||||||
|
@ -31,14 +36,16 @@ test "decodes a salmon with a changed magic key", %{conn: conn} do
|
||||||
# Set a wrong magic-key for a user so it has to refetch
|
# Set a wrong magic-key for a user so it has to refetch
|
||||||
salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1")
|
salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1")
|
||||||
# Wrong key
|
# Wrong key
|
||||||
info =
|
info_cng =
|
||||||
salmon_user.info
|
User.Info.remote_user_creation(salmon_user.info, %{
|
||||||
|> Map.put(
|
magic_key:
|
||||||
"magic_key",
|
|
||||||
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
|
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
|
||||||
)
|
})
|
||||||
|
|
||||||
Repo.update(User.info_changeset(salmon_user, %{info: info}))
|
cng =
|
||||||
|
Ecto.Changeset.change(salmon_user)
|
||||||
|
|> Ecto.Changeset.put_embed(:info, info_cng)
|
||||||
|
|> Repo.update()
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
|
|
@ -6,6 +6,11 @@ defmodule Pleroma.Web.OStatusTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import ExUnit.CaptureLog
|
import ExUnit.CaptureLog
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "don't insert create notes twice" do
|
test "don't insert create notes twice" do
|
||||||
incoming = File.read!("test/fixtures/incoming_note_activity.xml")
|
incoming = File.read!("test/fixtures/incoming_note_activity.xml")
|
||||||
{:ok, [activity]} = OStatus.handle_incoming(incoming)
|
{:ok, [activity]} = OStatus.handle_incoming(incoming)
|
||||||
|
@ -17,7 +22,7 @@ test "handle incoming note - GS, Salmon" do
|
||||||
{:ok, [activity]} = OStatus.handle_incoming(incoming)
|
{:ok, [activity]} = OStatus.handle_incoming(incoming)
|
||||||
|
|
||||||
user = User.get_by_ap_id(activity.data["actor"])
|
user = User.get_by_ap_id(activity.data["actor"])
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
assert activity.data["type"] == "Create"
|
assert activity.data["type"] == "Create"
|
||||||
assert activity.data["object"]["type"] == "Note"
|
assert activity.data["object"]["type"] == "Note"
|
||||||
|
|
||||||
|
@ -319,7 +324,7 @@ test "tries to use the information in poco fields" do
|
||||||
assert user.name == "Constance Variable"
|
assert user.name == "Constance Variable"
|
||||||
assert user.nickname == "lambadalambda@social.heldscal.la"
|
assert user.nickname == "lambadalambda@social.heldscal.la"
|
||||||
assert user.local == false
|
assert user.local == false
|
||||||
assert user.info["uri"] == uri
|
assert user.info.uri == uri
|
||||||
assert user.ap_id == uri
|
assert user.ap_id == uri
|
||||||
assert user.bio == "Call me Deacon Blues."
|
assert user.bio == "Call me Deacon Blues."
|
||||||
assert user.avatar["type"] == "Image"
|
assert user.avatar["type"] == "Image"
|
||||||
|
@ -329,6 +334,38 @@ test "tries to use the information in poco fields" do
|
||||||
assert user == user_again
|
assert user == user_again
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "find_or_make_user sets all the nessary input fields" do
|
||||||
|
uri = "https://social.heldscal.la/user/23211"
|
||||||
|
{:ok, user} = OStatus.find_or_make_user(uri)
|
||||||
|
|
||||||
|
assert user.info ==
|
||||||
|
%Pleroma.User.Info{
|
||||||
|
id: user.info.id,
|
||||||
|
ap_enabled: false,
|
||||||
|
background: %{},
|
||||||
|
banner: %{},
|
||||||
|
blocks: [],
|
||||||
|
deactivated: false,
|
||||||
|
default_scope: "public",
|
||||||
|
domain_blocks: [],
|
||||||
|
follower_count: 0,
|
||||||
|
is_admin: false,
|
||||||
|
is_moderator: false,
|
||||||
|
keys: nil,
|
||||||
|
locked: false,
|
||||||
|
no_rich_text: false,
|
||||||
|
note_count: 0,
|
||||||
|
settings: nil,
|
||||||
|
source_data: %{},
|
||||||
|
hub: "https://social.heldscal.la/main/push/hub",
|
||||||
|
magic_key:
|
||||||
|
"RSA.uzg6r1peZU0vXGADWxGJ0PE34WvmhjUmydbX5YYdOiXfODVLwCMi1umGoqUDm-mRu4vNEdFBVJU1CpFA7dKzWgIsqsa501i2XqElmEveXRLvNRWFB6nG03Q5OUY2as8eE54BJm0p20GkMfIJGwP6TSFb-ICp3QjzbatuSPJ6xCE=.AQAB",
|
||||||
|
salmon: "https://social.heldscal.la/main/salmon/user/23211",
|
||||||
|
topic: "https://social.heldscal.la/api/statuses/user_timeline/23211.atom",
|
||||||
|
uri: "https://social.heldscal.la/user/23211"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
test "find_make_or_update_user takes an author element and returns an updated user" do
|
test "find_make_or_update_user takes an author element and returns an updated user" do
|
||||||
uri = "https://social.heldscal.la/user/23211"
|
uri = "https://social.heldscal.la/user/23211"
|
||||||
|
|
||||||
|
@ -447,7 +484,7 @@ test "it works for atom notes, too" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it doesn't add nil in the do field" do
|
test "it doesn't add nil in the to field" do
|
||||||
incoming = File.read!("test/fixtures/nil_mention_entry.xml")
|
incoming = File.read!("test/fixtures/nil_mention_entry.xml")
|
||||||
{:ok, [activity]} = OStatus.handle_incoming(incoming)
|
{:ok, [activity]} = OStatus.handle_incoming(incoming)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Web.OStatus.UserRepresenterTest do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
test "returns a user with id, uri, name and link" do
|
test "returns a user with id, uri, name and link" do
|
||||||
user = build(:user, nickname: "レイン")
|
user = insert(:user, %{nickname: "レイン"})
|
||||||
tuple = UserRepresenter.to_simple_form(user)
|
tuple = UserRepresenter.to_simple_form(user)
|
||||||
|
|
||||||
res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> to_string
|
res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> to_string
|
||||||
|
|
|
@ -3,6 +3,7 @@ defmodule Pleroma.Web.Salmon.SalmonTest do
|
||||||
alias Pleroma.Web.Salmon
|
alias Pleroma.Web.Salmon
|
||||||
alias Pleroma.{Repo, Activity, User}
|
alias Pleroma.{Repo, Activity, User}
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
@magickey "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwQhh-1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
|
@magickey "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwQhh-1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
|
||||||
|
|
||||||
|
@ -10,6 +11,11 @@ defmodule Pleroma.Web.Salmon.SalmonTest do
|
||||||
|
|
||||||
@magickey_friendica "RSA.AMwa8FUs2fWEjX0xN7yRQgegQffhBpuKNC6fa5VNSVorFjGZhRrlPMn7TQOeihlc9lBz2OsHlIedbYn2uJ7yCs0.AQAB"
|
@magickey_friendica "RSA.AMwa8FUs2fWEjX0xN7yRQgegQffhBpuKNC6fa5VNSVorFjGZhRrlPMn7TQOeihlc9lBz2OsHlIedbYn2uJ7yCs0.AQAB"
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "decodes a salmon" do
|
test "decodes a salmon" do
|
||||||
{:ok, salmon} = File.read("test/fixtures/salmon.xml")
|
{:ok, salmon} = File.read("test/fixtures/salmon.xml")
|
||||||
{:ok, doc} = Salmon.decode_and_validate(@magickey, salmon)
|
{:ok, doc} = Salmon.decode_and_validate(@magickey, salmon)
|
||||||
|
|
|
@ -58,7 +58,7 @@ test "a like activity" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "an activity" do
|
test "an activity" do
|
||||||
{:ok, user} = UserBuilder.insert()
|
user = insert(:user)
|
||||||
# {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
|
# {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
|
||||||
mentioned_user = insert(:user, %{nickname: "shp"})
|
mentioned_user = insert(:user, %{nickname: "shp"})
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,42 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
describe "POST /api/account/update_profile_banner" do
|
||||||
|
test "it updates the banner", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
new_banner =
|
||||||
|
"data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => new_banner})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
user = Repo.get(User, user.id)
|
||||||
|
assert user.info.banner["type"] == "Image"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "POST /api/qvitter/update_background_image" do
|
||||||
|
test "it updates the background", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
new_bg =
|
||||||
|
"data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => new_bg})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
user = Repo.get(User, user.id)
|
||||||
|
assert user.info.background["type"] == "Image"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "POST /api/account/verify_credentials" do
|
describe "POST /api/account/verify_credentials" do
|
||||||
setup [:valid_user]
|
setup [:valid_user]
|
||||||
|
|
||||||
|
@ -31,26 +67,6 @@ test "with credentials", %{conn: conn, user: user} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST /api/account/most_recent_notification" do
|
|
||||||
setup [:valid_user]
|
|
||||||
|
|
||||||
test "without valid credentials", %{conn: conn} do
|
|
||||||
conn = post(conn, "/api/account/most_recent_notification.json")
|
|
||||||
assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "with credentials", %{conn: conn, user: user} do
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> with_credentials(user.nickname, "test")
|
|
||||||
|> post("/api/account/most_recent_notification.json", %{id: "200"})
|
|
||||||
|
|
||||||
assert json_response(conn, 200)
|
|
||||||
user = User.get_by_nickname(user.nickname)
|
|
||||||
assert user.info["most_recent_notification"] == 200
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "POST /statuses/update.json" do
|
describe "POST /statuses/update.json" do
|
||||||
setup [:valid_user]
|
setup [:valid_user]
|
||||||
|
|
||||||
|
@ -87,7 +103,7 @@ test "with credentials", %{conn: conn, user: user} do
|
||||||
|
|
||||||
describe "GET /statuses/public_timeline.json" do
|
describe "GET /statuses/public_timeline.json" do
|
||||||
test "returns statuses", %{conn: conn} do
|
test "returns statuses", %{conn: conn} do
|
||||||
{:ok, user} = UserBuilder.insert()
|
user = insert(:user)
|
||||||
activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
|
activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
|
||||||
ActivityBuilder.insert_list(10, %{}, %{user: user})
|
ActivityBuilder.insert_list(10, %{}, %{user: user})
|
||||||
since_id = List.last(activities).id
|
since_id = List.last(activities).id
|
||||||
|
@ -591,7 +607,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|
||||||
|> post("/api/blocks/destroy.json", %{user_id: blocked.id})
|
|> post("/api/blocks/destroy.json", %{user_id: blocked.id})
|
||||||
|
|
||||||
current_user = Repo.get(User, current_user.id)
|
current_user = Repo.get(User, current_user.id)
|
||||||
assert current_user.info["blocks"] == []
|
assert current_user.info.blocks == []
|
||||||
|
|
||||||
assert json_response(conn, 200) ==
|
assert json_response(conn, 200) ==
|
||||||
UserView.render("show.json", %{user: blocked, for: current_user})
|
UserView.render("show.json", %{user: blocked, for: current_user})
|
||||||
|
@ -939,18 +955,21 @@ test "it returns a user's friends", %{conn: conn} do
|
||||||
describe "POST /api/account/update_profile.json" do
|
describe "POST /api/account/update_profile.json" do
|
||||||
test "it updates a user's profile", %{conn: conn} do
|
test "it updates a user's profile", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
user2 = insert(:user)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> post("/api/account/update_profile.json", %{
|
|> post("/api/account/update_profile.json", %{
|
||||||
"name" => "new name",
|
"name" => "new name",
|
||||||
"description" => "new description"
|
"description" => "hi @#{user2.nickname}"
|
||||||
})
|
})
|
||||||
|
|
||||||
user = Repo.get!(User, user.id)
|
user = Repo.get!(User, user.id)
|
||||||
assert user.name == "new name"
|
assert user.name == "new name"
|
||||||
assert user.bio == "new description"
|
|
||||||
|
assert user.bio ==
|
||||||
|
"hi <span><a class='mention' href='#{user2.ap_id}'>@<span>#{user2.nickname}</span></a></span>"
|
||||||
|
|
||||||
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
|
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
|
||||||
end
|
end
|
||||||
|
@ -966,7 +985,7 @@ test "it locks an account", %{conn: conn} do
|
||||||
})
|
})
|
||||||
|
|
||||||
user = Repo.get!(User, user.id)
|
user = Repo.get!(User, user.id)
|
||||||
assert user.info["locked"] == true
|
assert user.info.locked == true
|
||||||
|
|
||||||
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
|
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
|
||||||
end
|
end
|
||||||
|
@ -982,7 +1001,7 @@ test "it unlocks an account", %{conn: conn} do
|
||||||
})
|
})
|
||||||
|
|
||||||
user = Repo.get!(User, user.id)
|
user = Repo.get!(User, user.id)
|
||||||
assert user.info["locked"] == false
|
assert user.info.locked == false
|
||||||
|
|
||||||
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
|
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
|
||||||
end
|
end
|
||||||
|
@ -1153,10 +1172,10 @@ test "with credentials and valid password", %{conn: conn, user: current_user} do
|
||||||
|
|
||||||
describe "GET /api/pleroma/friend_requests" do
|
describe "GET /api/pleroma/friend_requests" do
|
||||||
test "it lists friend requests" do
|
test "it lists friend requests" do
|
||||||
user = insert(:user, %{info: %{"locked" => true}})
|
user = insert(:user)
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
||||||
{:ok, activity} = ActivityPub.follow(other_user, user)
|
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||||
|
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
@ -1175,10 +1194,10 @@ test "it lists friend requests" do
|
||||||
|
|
||||||
describe "POST /api/pleroma/friendships/approve" do
|
describe "POST /api/pleroma/friendships/approve" do
|
||||||
test "it approves a friend request" do
|
test "it approves a friend request" do
|
||||||
user = insert(:user, %{info: %{"locked" => true}})
|
user = insert(:user)
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
||||||
{:ok, activity} = ActivityPub.follow(other_user, user)
|
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||||
|
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
@ -1198,10 +1217,10 @@ test "it approves a friend request" do
|
||||||
|
|
||||||
describe "POST /api/pleroma/friendships/deny" do
|
describe "POST /api/pleroma/friendships/deny" do
|
||||||
test "it denies a friend request" do
|
test "it denies a friend request" do
|
||||||
user = insert(:user, %{info: %{"locked" => true}})
|
user = insert(:user)
|
||||||
other_user = insert(:user)
|
other_user = insert(:user)
|
||||||
|
|
||||||
{:ok, activity} = ActivityPub.follow(other_user, user)
|
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||||
|
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
other_user = Repo.get(User, other_user.id)
|
other_user = Repo.get(User, other_user.id)
|
||||||
|
|
|
@ -10,7 +10,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
|
||||||
|
|
||||||
test "create a status" do
|
test "create a status" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
_mentioned_user = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
|
_mentioned_user = insert(:user, %{nickname: "shp", ap_id: "shp"})
|
||||||
|
|
||||||
object_data = %{
|
object_data = %{
|
||||||
"type" => "Image",
|
"type" => "Image",
|
||||||
|
@ -67,7 +67,7 @@ test "create a status" do
|
||||||
|
|
||||||
user = User.get_by_ap_id(user.ap_id)
|
user = User.get_by_ap_id(user.ap_id)
|
||||||
|
|
||||||
assert user.info["note_count"] == 1
|
assert user.info.note_count == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create a status that is a reply" do
|
test "create a status that is a reply" do
|
||||||
|
@ -116,7 +116,7 @@ test "Follow another user using screen_name" do
|
||||||
assert User.ap_followers(followed) in user.following
|
assert User.ap_followers(followed) in user.following
|
||||||
|
|
||||||
followed = User.get_by_ap_id(followed.ap_id)
|
followed = User.get_by_ap_id(followed.ap_id)
|
||||||
assert followed.info["follower_count"] == 1
|
assert followed.info.follower_count == 1
|
||||||
|
|
||||||
{:error, msg} = TwitterAPI.follow(user, %{"screen_name" => followed.nickname})
|
{:error, msg} = TwitterAPI.follow(user, %{"screen_name" => followed.nickname})
|
||||||
assert msg == "Could not follow user: #{followed.nickname} is already on your list."
|
assert msg == "Could not follow user: #{followed.nickname} is already on your list."
|
||||||
|
@ -169,7 +169,7 @@ test "Unblock another user using user_id" do
|
||||||
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"user_id" => unblocked.id})
|
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"user_id" => unblocked.id})
|
||||||
|
|
||||||
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"user_id" => unblocked.id})
|
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"user_id" => unblocked.id})
|
||||||
assert user.info["blocks"] == []
|
assert user.info.blocks == []
|
||||||
end
|
end
|
||||||
|
|
||||||
test "Unblock another user using screen_name" do
|
test "Unblock another user using screen_name" do
|
||||||
|
@ -178,7 +178,7 @@ test "Unblock another user using screen_name" do
|
||||||
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"screen_name" => unblocked.nickname})
|
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"screen_name" => unblocked.nickname})
|
||||||
|
|
||||||
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"screen_name" => unblocked.nickname})
|
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"screen_name" => unblocked.nickname})
|
||||||
assert user.info["blocks"] == []
|
assert user.info.blocks == []
|
||||||
end
|
end
|
||||||
|
|
||||||
test "upload a file" do
|
test "upload a file" do
|
||||||
|
@ -257,6 +257,35 @@ test "it registers a new user and returns the user." do
|
||||||
UserView.render("show.json", %{user: fetched_user})
|
UserView.render("show.json", %{user: fetched_user})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it registers a new user and parses mentions in the bio" do
|
||||||
|
data1 = %{
|
||||||
|
"nickname" => "john",
|
||||||
|
"email" => "john@gmail.com",
|
||||||
|
"fullname" => "John Doe",
|
||||||
|
"bio" => "test",
|
||||||
|
"password" => "bear",
|
||||||
|
"confirm" => "bear"
|
||||||
|
}
|
||||||
|
|
||||||
|
{:ok, user1} = TwitterAPI.register_user(data1)
|
||||||
|
|
||||||
|
data2 = %{
|
||||||
|
"nickname" => "lain",
|
||||||
|
"email" => "lain@wired.jp",
|
||||||
|
"fullname" => "lain iwakura",
|
||||||
|
"bio" => "@john test",
|
||||||
|
"password" => "bear",
|
||||||
|
"confirm" => "bear"
|
||||||
|
}
|
||||||
|
|
||||||
|
{:ok, user2} = TwitterAPI.register_user(data2)
|
||||||
|
|
||||||
|
expected_text =
|
||||||
|
"<span><a class='mention' href='#{user1.ap_id}'>@<span>john</span></a></span> test"
|
||||||
|
|
||||||
|
assert user2.bio == expected_text
|
||||||
|
end
|
||||||
|
|
||||||
@moduletag skip: "needs 'registrations_open: false' in config"
|
@moduletag skip: "needs 'registrations_open: false' in config"
|
||||||
test "it registers a new user via invite token and returns the user." do
|
test "it registers a new user via invite token and returns the user." do
|
||||||
{:ok, token} = UserInviteToken.create_token()
|
{:ok, token} = UserInviteToken.create_token()
|
||||||
|
|
|
@ -31,10 +31,10 @@ test "A user with emoji in username", %{user: user} do
|
||||||
expected =
|
expected =
|
||||||
"<img height=\"32px\" width=\"32px\" alt=\"karjalanpiirakka\" title=\"karjalanpiirakka\" src=\"/file.png\" /> man"
|
"<img height=\"32px\" width=\"32px\" alt=\"karjalanpiirakka\" title=\"karjalanpiirakka\" src=\"/file.png\" /> man"
|
||||||
|
|
||||||
user = %{
|
user =
|
||||||
user
|
insert(:user, %{
|
||||||
| info: %{
|
info: %{
|
||||||
"source_data" => %{
|
source_data: %{
|
||||||
"tag" => [
|
"tag" => [
|
||||||
%{
|
%{
|
||||||
"type" => "Emoji",
|
"type" => "Emoji",
|
||||||
|
@ -43,10 +43,10 @@ test "A user with emoji in username", %{user: user} do
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
name: ":karjalanpiirakka: man"
|
||||||
|
})
|
||||||
|
|
||||||
user = %{user | name: ":karjalanpiirakka: man"}
|
|
||||||
represented = UserView.render("show.json", %{user: user})
|
represented = UserView.render("show.json", %{user: user})
|
||||||
assert represented["name_html"] == expected
|
assert represented["name_html"] == expected
|
||||||
end
|
end
|
||||||
|
@ -103,7 +103,7 @@ test "A user" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "A user for a given other follower", %{user: user} do
|
test "A user for a given other follower", %{user: user} do
|
||||||
{:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
|
follower = insert(:user, %{following: [User.ap_followers(user)]})
|
||||||
{:ok, user} = User.update_follower_count(user)
|
{:ok, user} = User.update_follower_count(user)
|
||||||
image = "http://localhost:4001/images/avi.png"
|
image = "http://localhost:4001/images/avi.png"
|
||||||
banner = "http://localhost:4001/images/banner.png"
|
banner = "http://localhost:4001/images/banner.png"
|
||||||
|
@ -186,7 +186,7 @@ test "A user that follows you", %{user: user} do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "a user that is a moderator" do
|
test "a user that is a moderator" do
|
||||||
user = insert(:user, %{info: %{"is_moderator" => true}})
|
user = insert(:user, %{info: %{is_moderator: true}})
|
||||||
represented = UserView.render("show.json", %{user: user, for: user})
|
represented = UserView.render("show.json", %{user: user, for: user})
|
||||||
|
|
||||||
assert represented["rights"]["delete_others_notice"]
|
assert represented["rights"]["delete_others_notice"]
|
||||||
|
@ -250,7 +250,7 @@ test "a user with mastodon fields" do
|
||||||
user =
|
user =
|
||||||
insert(:user, %{
|
insert(:user, %{
|
||||||
info: %{
|
info: %{
|
||||||
"source_data" => %{
|
source_data: %{
|
||||||
"attachment" =>
|
"attachment" =>
|
||||||
Enum.map(fields, fn field -> Map.put(field, "type", "PropertyValue") end)
|
Enum.map(fields, fn field -> Map.put(field, "type", "PropertyValue") end)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@ defmodule Pleroma.Web.WebFingerTest do
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
alias Pleroma.Web.WebFinger
|
alias Pleroma.Web.WebFinger
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
describe "host meta" do
|
describe "host meta" do
|
||||||
test "returns a link to the xml lrdd" do
|
test "returns a link to the xml lrdd" do
|
||||||
|
@ -99,15 +105,15 @@ test "it gets the xrd endpoint for statusnet" do
|
||||||
describe "ensure_keys_present" do
|
describe "ensure_keys_present" do
|
||||||
test "it creates keys for a user and stores them in info" do
|
test "it creates keys for a user and stores them in info" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
refute is_binary(user.info["keys"])
|
refute is_binary(user.info.keys)
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
{:ok, user} = WebFinger.ensure_keys_present(user)
|
||||||
assert is_binary(user.info["keys"])
|
assert is_binary(user.info.keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it doesn't create keys if there already are some" do
|
test "it doesn't create keys if there already are some" do
|
||||||
user = insert(:user, %{info: %{"keys" => "xxx"}})
|
user = insert(:user, %{info: %{keys: "xxx"}})
|
||||||
{:ok, user} = WebFinger.ensure_keys_present(user)
|
{:ok, user} = WebFinger.ensure_keys_present(user)
|
||||||
assert user.info["keys"] == "xxx"
|
assert user.info.keys == "xxx"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,12 @@ defmodule Pleroma.Web.WebsubTest do
|
||||||
alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription}
|
alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription}
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
alias Pleroma.Web.Router.Helpers
|
alias Pleroma.Web.Router.Helpers
|
||||||
|
import Tesla.Mock
|
||||||
|
|
||||||
|
setup do
|
||||||
|
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
test "a verification of a request that is accepted" do
|
test "a verification of a request that is accepted" do
|
||||||
sub = insert(:websub_subscription)
|
sub = insert(:websub_subscription)
|
||||||
|
@ -26,8 +32,8 @@ test "a verification of a request that is accepted" do
|
||||||
assert String.to_integer(seconds) > 0
|
assert String.to_integer(seconds) > 0
|
||||||
|
|
||||||
{:ok,
|
{:ok,
|
||||||
%HTTPoison.Response{
|
%Tesla.Env{
|
||||||
status_code: 200,
|
status: 200,
|
||||||
body: challenge
|
body: challenge
|
||||||
}}
|
}}
|
||||||
end
|
end
|
||||||
|
@ -41,8 +47,8 @@ test "a verification of a request that doesn't return 200" do
|
||||||
|
|
||||||
getter = fn _path, _headers, _options ->
|
getter = fn _path, _headers, _options ->
|
||||||
{:ok,
|
{:ok,
|
||||||
%HTTPoison.Response{
|
%Tesla.Env{
|
||||||
status_code: 500,
|
status: 500,
|
||||||
body: ""
|
body: ""
|
||||||
}}
|
}}
|
||||||
end
|
end
|
||||||
|
@ -99,7 +105,7 @@ def accepting_verifier(subscription) do
|
||||||
|
|
||||||
test "initiate a subscription for a given user and topic" do
|
test "initiate a subscription for a given user and topic" do
|
||||||
subscriber = insert(:user)
|
subscriber = insert(:user)
|
||||||
user = insert(:user, %{info: %{"topic" => "some_topic", "hub" => "some_hub"}})
|
user = insert(:user, %{info: %Pleroma.User.Info{topic: "some_topic", hub: "some_hub"}})
|
||||||
|
|
||||||
{:ok, websub} = Websub.subscribe(subscriber, user, &accepting_verifier/1)
|
{:ok, websub} = Websub.subscribe(subscriber, user, &accepting_verifier/1)
|
||||||
assert websub.subscribers == [subscriber.ap_id]
|
assert websub.subscribers == [subscriber.ap_id]
|
||||||
|
@ -113,12 +119,7 @@ test "initiate a subscription for a given user and topic" do
|
||||||
test "discovers the hub and canonical url" do
|
test "discovers the hub and canonical url" do
|
||||||
topic = "https://mastodon.social/users/lambadalambda.atom"
|
topic = "https://mastodon.social/users/lambadalambda.atom"
|
||||||
|
|
||||||
getter = fn ^topic ->
|
{:ok, discovered} = Websub.gather_feed_data(topic)
|
||||||
doc = File.read!("test/fixtures/lambadalambda.atom")
|
|
||||||
{:ok, %{status_code: 200, body: doc}}
|
|
||||||
end
|
|
||||||
|
|
||||||
{:ok, discovered} = Websub.gather_feed_data(topic, getter)
|
|
||||||
|
|
||||||
expected = %{
|
expected = %{
|
||||||
"hub" => "https://mastodon.social/api/push",
|
"hub" => "https://mastodon.social/api/push",
|
||||||
|
@ -158,7 +159,7 @@ test "calls the hub, requests topic" do
|
||||||
websub.id
|
websub.id
|
||||||
)
|
)
|
||||||
|
|
||||||
{:ok, %{status_code: 202}}
|
{:ok, %{status: 202}}
|
||||||
end
|
end
|
||||||
|
|
||||||
task = Task.async(fn -> Websub.request_subscription(websub, poster) end)
|
task = Task.async(fn -> Websub.request_subscription(websub, poster) end)
|
||||||
|
@ -177,7 +178,7 @@ test "rejects the subscription if it can't be accepted" do
|
||||||
websub = insert(:websub_client_subscription, %{hub: hub, topic: topic})
|
websub = insert(:websub_client_subscription, %{hub: hub, topic: topic})
|
||||||
|
|
||||||
poster = fn ^hub, {:form, _data}, _headers ->
|
poster = fn ^hub, {:form, _data}, _headers ->
|
||||||
{:ok, %{status_code: 202}}
|
{:ok, %{status: 202}}
|
||||||
end
|
end
|
||||||
|
|
||||||
{:error, websub} = Websub.request_subscription(websub, poster, 1000)
|
{:error, websub} = Websub.request_subscription(websub, poster, 1000)
|
||||||
|
@ -186,7 +187,7 @@ test "rejects the subscription if it can't be accepted" do
|
||||||
websub = insert(:websub_client_subscription, %{hub: hub, topic: topic})
|
websub = insert(:websub_client_subscription, %{hub: hub, topic: topic})
|
||||||
|
|
||||||
poster = fn ^hub, {:form, _data}, _headers ->
|
poster = fn ^hub, {:form, _data}, _headers ->
|
||||||
{:ok, %{status_code: 400}}
|
{:ok, %{status: 400}}
|
||||||
end
|
end
|
||||||
|
|
||||||
{:error, websub} = Websub.request_subscription(websub, poster, 1000)
|
{:error, websub} = Websub.request_subscription(websub, poster, 1000)
|
||||||
|
@ -209,6 +210,7 @@ test "it renews subscriptions that have less than a day of time left" do
|
||||||
insert(:websub_client_subscription, %{
|
insert(:websub_client_subscription, %{
|
||||||
valid_until: NaiveDateTime.add(now, 2 * day),
|
valid_until: NaiveDateTime.add(now, 2 * day),
|
||||||
topic: "http://example.org/still_good",
|
topic: "http://example.org/still_good",
|
||||||
|
hub: "http://example.org/still_good",
|
||||||
state: "accepted"
|
state: "accepted"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -216,6 +218,7 @@ test "it renews subscriptions that have less than a day of time left" do
|
||||||
insert(:websub_client_subscription, %{
|
insert(:websub_client_subscription, %{
|
||||||
valid_until: NaiveDateTime.add(now, day - 100),
|
valid_until: NaiveDateTime.add(now, day - 100),
|
||||||
topic: "http://example.org/needs_refresh",
|
topic: "http://example.org/needs_refresh",
|
||||||
|
hub: "http://example.org/needs_refresh",
|
||||||
state: "accepted"
|
state: "accepted"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue