commit
ef318fb8a9
@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
# PROVIDE: pleroma
|
||||
# REQUIRE: DAEMON pgsql
|
||||
|
||||
if [ -f /etc/rc.subr ]; then
|
||||
. /etc/rc.subr
|
||||
fi
|
||||
|
||||
name="pleroma"
|
||||
rcvar=${name}
|
||||
command="/usr/pkg/bin/elixir"
|
||||
command_args="--detached -S /usr/pkg/bin/mix phx.server"
|
||||
start_precmd="ulimit -n unlimited"
|
||||
pidfile="/dev/null"
|
||||
|
||||
pleroma_chdir="${pleroma_home}/pleroma"
|
||||
pleroma_env="HOME=${pleroma_home} MIX_ENV=prod"
|
||||
|
||||
check_pidfile()
|
||||
{
|
||||
pid=$(pgrep -U "${pleroma_user}" /bin/beam.smp$)
|
||||
echo -n "${pid}"
|
||||
}
|
||||
|
||||
if [ -f /etc/rc.subr -a -d /etc/rc.d -a -f /etc/rc.d/DAEMON ]; then
|
||||
# newer NetBSD
|
||||
load_rc_config ${name}
|
||||
run_rc_command "$1"
|
||||
else
|
||||
# ancient NetBSD, Solaris and illumos, Linux, etc...
|
||||
cmd=${1:-start}
|
||||
|
||||
case ${cmd} in
|
||||
start)
|
||||
echo "Starting ${name}."
|
||||
${start_cmd}
|
||||
;;
|
||||
|
||||
stop)
|
||||
echo "Stopping ${name}."
|
||||
check_pidfile
|
||||
! [ -n ${pid} ] && kill ${pid}
|
||||
;;
|
||||
|
||||
restart)
|
||||
( $0 stop )
|
||||
sleep 5
|
||||
$0 start
|
||||
;;
|
||||
|
||||
*)
|
||||
echo 1>&2 "Usage: $0 [start|stop|restart]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
fi
|
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Default httpd.conf file for Pleroma on OpenBSD
|
||||
# Simple installation instructions
|
||||
# 1. Place file in /etc
|
||||
# 2. Replace <IPv4 address> with your public IP address
|
||||
# 3. If using IPv6, uncomment IPv6 lines and replace <IPv6 address> with your public IPv6 address
|
||||
# 4. Check file using 'doas httpd -n'
|
||||
# 5. Enable and start httpd:
|
||||
# # doas rcctl enable httpd
|
||||
# # doas rcctl start httpd
|
||||
#
|
||||
|
||||
ext_inet="<IPv4 address>"
|
||||
#ext_inet6="<IPv6 address>"
|
||||
|
||||
server "default" {
|
||||
listen on $ext_inet port 80 # Comment to disable listening on IPv4
|
||||
# listen on $ext_inet6 port 80 # Comment to disable listening on IPv6
|
||||
listen on 127.0.0.1 port 80 # Do NOT comment this line
|
||||
|
||||
log syslog
|
||||
directory no index
|
||||
|
||||
location "/.well-known/acme-challenge/*" {
|
||||
root "/acme"
|
||||
request strip 2
|
||||
}
|
||||
|
||||
location "/robots.txt" { root "/htdocs/local/" }
|
||||
location "/*" { block return 302 "https://$HTTP_HOST$REQUEST_URI" }
|
||||
}
|
||||
|
||||
types {
|
||||
include "/usr/share/misc/mime.types"
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
#!/bin/ksh
|
||||
#
|
||||
# Default init file for Pleroma on OpenBSD
|
||||
#
|
||||
# Simple installation instructions:
|
||||
# 1. Install Pleroma per wiki instructions
|
||||
# 2. Place this pleromad file in /etc/rc.d
|
||||
# 3. Enable and start Pleroma
|
||||
# # doas rcctl enable pleromad
|
||||
# # doas rcctl start pleromad
|
||||
#
|
||||
|
||||
daemon="/usr/local/bin/elixir"
|
||||
daemon_flags="--detached -S /usr/local/bin/mix phx.server"
|
||||
daemon_user="_pleroma"
|
||||
|
||||
. /etc/rc.d/rc.subr
|
||||
|
||||
rc_reload=NO
|
||||
pexp="phx.server"
|
||||
|
||||
rc_check() {
|
||||
pgrep -q -U _pleroma -f "phx.server"
|
||||
}
|
||||
|
||||
rc_start() {
|
||||
${rcexec} "cd pleroma; ${daemon} ${daemon_flags}"
|
||||
}
|
||||
|
||||
rc_stop() {
|
||||
pkill -q -U _pleroma -f "phx.server"
|
||||
}
|
||||
|
||||
rc_cmd $1
|
@ -0,0 +1,44 @@
|
||||
#
|
||||
# Default relayd.conf file for Pleroma on OpenBSD
|
||||
# Simple installation instructions:
|
||||
# 1. Place in /etc
|
||||
# 2. Replace <ipaddr> with your public IPv4 address
|
||||
# 3. If using IPv6i, uncomment IPv6 lines and replace <ip6addr> with your public IPv6 address
|
||||
# 4. Check file using 'doas relayd -n'
|
||||
# 5. Reload/start relayd
|
||||
# # doas rcctl enable relayd
|
||||
# # doas rcctl start relayd
|
||||
#
|
||||
|
||||
ext_inet="<ipaddr>"
|
||||
#ext_inet6="<ip6addr>"
|
||||
|
||||
table <pleroma_server> { 127.0.0.1 }
|
||||
table <httpd_server> { 127.0.0.1 }
|
||||
|
||||
http protocol plerup { # Protocol for upstream pleroma server
|
||||
#tcp { nodelay, sack, socket buffer 65536, backlog 128 } # Uncomment and adjust as you see fit
|
||||
tls ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA0-POLY1305"
|
||||
tls ecdhe secp384r1
|
||||
|
||||
# Forward some paths to the local server (as pleroma won't respond to them as you might want)
|
||||
pass request quick path "/robots.txt" forward to <httpd_server>
|
||||
|
||||
# Append a bunch of headers
|
||||
match request header append "X-Forwarded-For" value "$REMOTE_ADDR" # This two header and the next one are not strictl required by pleroma but adding them won't hurt
|
||||
match request header append "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
|
||||
|
||||
match request header append "Connection" value "upgrade"
|
||||
|
||||
}
|
||||
|
||||
relay wwwtls {
|
||||
listen on $ext_inet port https tls # Comment to disable listening on IPv4
|
||||
# listen on $ext_inet6 port https tls # Comment to disable listening on IPv6
|
||||
|
||||
protocol plerup
|
||||
|
||||
forward to <pleroma_server> port 4000 check http "/" code 200
|
||||
forward to <httpd_server> port 80 check http "/robots.txt" code 200
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
defmodule Pleroma.Captcha do
|
||||
use GenServer
|
||||
|
||||
@ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
|
||||
|
||||
@doc false
|
||||
def start_link() do
|
||||
GenServer.start_link(__MODULE__, [], name: __MODULE__)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def init(_) do
|
||||
# Create a ETS table to store captchas
|
||||
ets_name = Module.concat(method(), Ets)
|
||||
^ets_name = :ets.new(Module.concat(method(), Ets), @ets_options)
|
||||
|
||||
# Clean up old captchas every few minutes
|
||||
seconds_retained = Pleroma.Config.get!([__MODULE__, :seconds_retained])
|
||||
Process.send_after(self(), :cleanup, 1000 * seconds_retained)
|
||||
|
||||
{:ok, nil}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Ask the configured captcha service for a new captcha
|
||||
"""
|
||||
def new() do
|
||||
GenServer.call(__MODULE__, :new)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Ask the configured captcha service to validate the captcha
|
||||
"""
|
||||
def validate(token, captcha) do
|
||||
GenServer.call(__MODULE__, {:validate, token, captcha})
|
||||
end
|
||||
|
||||
@doc false
|
||||
def handle_call(:new, _from, state) do
|
||||
enabled = Pleroma.Config.get([__MODULE__, :enabled])
|
||||
|
||||
if !enabled do
|
||||
{:reply, %{type: :none}, state}
|
||||
else
|
||||
{:reply, method().new(), state}
|
||||
end
|
||||
end
|
||||
|
||||
@doc false
|
||||
def handle_call({:validate, token, captcha}, _from, state) do
|
||||
{:reply, method().validate(token, captcha), state}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def handle_info(:cleanup, state) do
|
||||
:ok = method().cleanup()
|
||||
|
||||
seconds_retained = Pleroma.Config.get!([__MODULE__, :seconds_retained])
|
||||
# Schedule the next clenup
|
||||
Process.send_after(self(), :cleanup, 1000 * seconds_retained)
|
||||
|
||||
{:noreply, state}
|
||||
end
|
||||
|
||||
defp method, do: Pleroma.Config.get!([__MODULE__, :method])
|
||||
end
|
@ -0,0 +1,28 @@
|
||||
defmodule Pleroma.Captcha.Service do
|
||||
@doc """
|
||||
Request new captcha from a captcha service.
|
||||
|
||||
Returns:
|
||||
|
||||
Service-specific data for using the newly created captcha
|
||||
"""
|
||||
@callback new() :: map
|
||||
|
||||
@doc """
|
||||
Validated the provided captcha solution.
|
||||
|
||||
Arguments:
|
||||
* `token` the captcha is associated with
|
||||
* `captcha` solution of the captcha to validate
|
||||
|
||||
Returns:
|
||||
|
||||
`true` if captcha is valid, `false` if not
|
||||
"""
|
||||
@callback validate(token :: String.t(), captcha :: String.t()) :: boolean
|
||||
|
||||
@doc """
|
||||
This function is called periodically to clean up old captchas
|
||||
"""
|
||||
@callback cleanup() :: :ok
|
||||
end
|
@ -0,0 +1,67 @@
|
||||
defmodule Pleroma.Captcha.Kocaptcha do
|
||||
alias Calendar.DateTime
|
||||
|
||||
alias Pleroma.Captcha.Service
|
||||
@behaviour Service
|
||||
|
||||
@ets __MODULE__.Ets
|
||||
|
||||
@impl Service
|
||||
def new() do
|
||||
endpoint = Pleroma.Config.get!([__MODULE__, :endpoint])
|
||||
|
||||
case Tesla.get(endpoint <> "/new") do
|
||||
{:error, _} ->
|
||||
%{error: "Kocaptcha service unavailable"}
|
||||
|
||||
{:ok, res} ->
|
||||
json_resp = Poison.decode!(res.body)
|
||||
|
||||
token = json_resp["token"]
|
||||
|
||||
true =
|
||||
:ets.insert(
|
||||
@ets,
|
||||
{token, json_resp["md5"], DateTime.now_utc() |> DateTime.Format.unix()}
|
||||
)
|
||||
|
||||
%{type: :kocaptcha, token: token, url: endpoint <> json_resp["url"]}
|
||||
end
|
||||
end
|
||||
|
||||
@impl Service
|
||||
def validate(token, captcha) do
|
||||
with false <- is_nil(captcha),
|
||||
[{^token, saved_md5, _}] <- :ets.lookup(@ets, token),
|
||||
true <- :crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(saved_md5) do
|
||||
# Clear the saved value
|
||||
:ets.delete(@ets, token)
|
||||
|
||||
true
|
||||
else
|
||||
_ -> false
|
||||
end
|
||||
end
|
||||
|
||||
@impl Service
|
||||
def cleanup() do
|
||||
seconds_retained = Pleroma.Config.get!([Pleroma.Captcha, :seconds_retained])
|
||||
# If the time in ETS is less than current_time - seconds_retained, then the time has
|
||||
# already passed
|
||||
delete_after =
|
||||
DateTime.subtract!(DateTime.now_utc(), seconds_retained) |> DateTime.Format.unix()
|
||||
|
||||
:ets.select_delete(
|
||||
@ets,
|
||||
[
|
||||
{
|
||||
{:_, :_, :"$1"},
|
||||
[{:<, :"$1", {:const, delete_after}}],
|
||||
[true]
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
@ -0,0 +1,54 @@
|
||||
defmodule Pleroma.Plugs.InstanceStatic do
|
||||
@moduledoc """
|
||||
This is a shim to call `Plug.Static` but with runtime `from` configuration.
|
||||
|
||||
Mountpoints are defined directly in the module to avoid calling the configuration for every request including non-static ones.
|
||||
"""
|
||||
@behaviour Plug
|
||||
|
||||
def file_path(path) do
|
||||
instance_path =
|
||||
Path.join(Pleroma.Config.get([:instance, :static_dir], "instance/static/"), path)
|
||||
|
||||
if File.exists?(instance_path) do
|
||||
instance_path
|
||||
else
|
||||
Path.join(Application.app_dir(:pleroma, "priv/static/"), path)
|
||||
end
|
||||
end
|
||||
|
||||
@only ~w(index.html static emoji packs sounds images instance favicon.png)
|
||||
|
||||
def init(opts) do
|
||||
opts
|
||||
|> Keyword.put(:from, "__unconfigured_instance_static_plug")
|
||||
|> Keyword.put(:at, "/__unconfigured_instance_static_plug")
|
||||
|> Plug.Static.init()
|
||||
end
|
||||
|
||||
for only <- @only do
|
||||
at = Plug.Router.Utils.split("/")
|
||||
|
||||
def call(conn = %{request_path: "/" <> unquote(only) <> _}, opts) do
|
||||
call_static(
|
||||
conn,
|
||||
opts,
|
||||
unquote(at),
|
||||
Pleroma.Config.get([:instance, :static_dir], "instance/static")
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def call(conn, _) do
|
||||
conn
|
||||
end
|
||||
|
||||
defp call_static(conn, opts, at, from) do
|
||||
opts =
|
||||
opts
|
||||
|> Map.put(:from, from)
|
||||
|> Map.put(:at, at)
|
||||
|
||||
Plug.Static.call(conn, opts)
|
||||
end
|
||||
end
|
@ -1,81 +0,0 @@
|
||||
defmodule Pleroma.Web.MastodonAPI.MastodonSocket do
|
||||
use Phoenix.Socket
|
||||
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
alias Pleroma.{User, Repo}
|
||||
|
||||
transport(
|
||||
:websocket,
|
||||
Phoenix.Transports.WebSocket.Raw,
|
||||
# We never receive data.
|
||||
timeout: :infinity
|
||||
)
|
||||
|
||||
@spec connect(params :: map(), Phoenix.Socket.t()) :: {:ok, Phoenix.Socket.t()} | :error
|
||||
def connect(%{"access_token" => token} = params, socket) do
|
||||
with %Token{user_id: user_id} <- Repo.get_by(Token, token: token),
|
||||
%User{} = user <- Repo.get(User, user_id),
|
||||
stream
|
||||
when stream in [
|
||||
"public",
|
||||
"public:local",
|
||||
"public:media",
|
||||
"public:local:media",
|
||||
"user",
|
||||
"direct",
|
||||
"list",
|
||||
"hashtag"
|
||||
] <- params["stream"] do
|
||||
topic =
|
||||
case stream do
|
||||
"hashtag" -> "hashtag:#{params["tag"]}"
|
||||
"list" -> "list:#{params["list"]}"
|
||||
_ -> stream
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:topic, topic)
|
||||
|> assign(:user, user)
|
||||
|
||||
Pleroma.Web.Streamer.add_socket(topic, socket)
|
||||
{:ok, socket}
|
||||
else
|
||||
_e -> :error
|
||||
end
|
||||
end
|
||||
|
||||
def connect(%{"stream" => stream} = params, socket)
|
||||
when stream in ["public", "public:local", "hashtag"] do
|
||||
topic =
|
||||
case stream do
|
||||
"hashtag" -> "hashtag:#{params["tag"]}"
|
||||
_ -> stream
|
||||
end
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> assign(:topic, topic)
|
||||
|
||||
Pleroma.Web.Streamer.add_socket(topic, socket)
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
def connect(_params, _socket), do: :error
|
||||
|
||||
def id(_), do: nil
|
||||
|
||||
def handle(:text, message, _state) do
|
||||
# | :ok
|
||||
# | state
|
||||
# | {:text, message}
|
||||
# | {:text, message, state}
|
||||
# | {:close, "Goodbye!"}
|
||||
{:text, message}
|
||||
end
|
||||
|
||||
def handle(:closed, _, %{socket: socket}) do
|
||||
topic = socket.assigns[:topic]
|
||||
Pleroma.Web.Streamer.remove_socket(topic, socket)
|
||||
end
|
||||
end
|
@ -0,0 +1,120 @@
|
||||
defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
||||
require Logger
|
||||
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
alias Pleroma.{User, Repo}
|
||||
|
||||
@behaviour :cowboy_websocket_handler
|
||||
|
||||
@streams [
|
||||
"public",
|
||||
"public:local",
|
||||
"public:media",
|
||||
"public:local:media",
|
||||
"user",
|
||||
"direct",
|
||||
"list",
|
||||
"hashtag"
|
||||
]
|
||||
@anonymous_streams ["public", "public:local", "hashtag"]
|
||||
|
||||
# Handled by periodic keepalive in Pleroma.Web.Streamer.
|
||||
@timeout :infinity
|
||||
|
||||
def init(_type, _req, _opts) do
|
||||
{:upgrade, :protocol, :cowboy_websocket}
|
||||
end
|
||||
|
||||
def websocket_init(_type, req, _opts) do
|
||||
with {qs, req} <- :cowboy_req.qs(req),
|
||||
params <- :cow_qs.parse_qs(qs),
|
||||
access_token <- List.keyfind(params, "access_token", 0),
|
||||
{_, stream} <- List.keyfind(params, "stream", 0),
|
||||
{:ok, user} <- allow_request(stream, access_token),
|
||||
topic when is_binary(topic) <- expand_topic(stream, params) do
|
||||
send(self(), :subscribe)
|
||||
{:ok, req, %{user: user, topic: topic}, @timeout}
|
||||
else
|
||||
{:error, code} ->
|
||||
Logger.debug("#{__MODULE__} denied connection: #{inspect(code)} - #{inspect(req)}")
|
||||
{:ok, req} = :cowboy_req.reply(code, req)
|
||||
{:shutdown, req}
|
||||
|
||||
error ->
|
||||
Logger.debug("#{__MODULE__} denied connection: #{inspect(error)} - #{inspect(req)}")
|
||||
{:shutdown, req}
|
||||
end
|
||||
end
|
||||
|
||||
# We never receive messages.
|
||||
def websocket_handle(_frame, req, state) do
|
||||
{:ok, req, state}
|
||||
end
|
||||
|
||||
def websocket_info(:subscribe, req, state) do
|
||||
Logger.debug(
|
||||
"#{__MODULE__} accepted websocket connection for user #{
|
||||
(state.user || %{id: "anonymous"}).id
|
||||
}, topic #{state.topic}"
|
||||
)
|
||||
|
||||
Pleroma.Web.Streamer.add_socket(state.topic, streamer_socket(state))
|
||||
{:ok, req, state}
|
||||
end
|
||||
|
||||
def websocket_info({:text, message}, req, state) do
|
||||
{:reply, {:text, message}, req, state}
|
||||
end
|
||||
|
||||
def websocket_terminate(reason, _req, state) do
|
||||
Logger.debug(
|
||||
"#{__MODULE__} terminating websocket connection for user #{
|
||||
(state.user || %{id: "anonymous"}).id
|
||||
}, topic #{state.topic || "?"}: #{inspect(reason)}"
|
||||
)
|
||||
|
||||
Pleroma.Web.Streamer.remove_socket(state.topic, streamer_socket(state))
|
||||
:ok
|
||||
end
|
||||
|
||||
# Public streams without authentication.
|
||||
defp allow_request(stream, nil) when stream in @anonymous_streams do
|
||||
{:ok, nil}
|
||||
end
|
||||
|
||||
# Authenticated streams.
|
||||
defp allow_request(stream, {"access_token", access_token}) when stream in @streams do
|
||||
with %Token{user_id: user_id} <- Repo.get_by(Token, token: access_token),
|
||||
user = %User{} <- Repo.get(User, user_id) do
|
||||
{:ok, user}
|
||||
else
|
||||
_ -> {:error, 403}
|
||||
end
|
||||
end
|
||||
|
||||
# Not authenticated.
|
||||
defp allow_request(stream, _) when stream in @streams, do: {:error, 403}
|
||||
|
||||
# No matching stream.
|
||||
defp allow_request(_, _), do: {:error, 404}
|
||||
|
||||
defp expand_topic("hashtag", params) do
|
||||
case List.keyfind(params, "tag", 0) do
|
||||
{_, tag} -> "hashtag:#{tag}"
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
defp expand_topic("list", params) do
|
||||
case List.keyfind(params, "list", 0) do
|
||||
{_, list} -> "list:#{list}"
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
defp expand_topic(topic, _), do: topic
|
||||
|
||||
defp streamer_socket(state) do
|
||||
%{transport_pid: self(), assigns: state}
|
||||
end
|
||||
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.ea00efb3229c8591fcc5249f0241b986.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.e076977b8e6c6844fb00.js></script><script type=text/javascript src=/static/js/vendor.cc4190750f6ed4d697bd.js></script><script type=text/javascript src=/static/js/app.67f548ecb9e9fd6b25b0.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><!--server-generated-meta--><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.285fa56c62b811bbd37880f7e2656b13.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.60e190da7cc4cc4711dc.js></script><script type=text/javascript src=/static/js/vendor.48d4753220bd83360796.js></script><script type=text/javascript src=/static/js/app.6cb7378f44092df9536a.js></script></body></html>
|
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
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
File diff suppressed because one or more lines are too long
@ -0,0 +1,2 @@
|
||||
!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(o,p){for(var c,l,s=0,i=[];s<o.length;s++)l=o[s],a[l]&&i.push.apply(i,a[l]),a[l]=0;for(c in p)Object.prototype.hasOwnProperty.call(p,c)&&(e[c]=p[c]);for(r&&r(o,p);i.length;)i.shift().call(null,t);if(p[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],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"48d4753220bd83360796",2:"6cb7378f44092df9536a"}[e]+".js",n.appendChild(o)}},t.m=e,t.c=n,t.p="/"}([]);
|
||||
//# sourceMappingURL=manifest.60e190da7cc4cc4711dc.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:"cc4190750f6ed4d697bd",2:"67f548ecb9e9fd6b25b0"}[e]+".js",n.appendChild(c)}},t.m=e,t.c=n,t.p="/"}([]);
|
||||
//# sourceMappingURL=manifest.e076977b8e6c6844fb00.js.map
|
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
@ -0,0 +1,40 @@
|
||||
defmodule Pleroma.CaptchaTest do
|
||||
use ExUnit.Case
|
||||
|
||||
import Tesla.Mock
|
||||
|
||||
alias Pleroma.Captcha.Kocaptcha
|
||||
|
||||
@ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
|
||||
|
||||
describe "Kocaptcha" do
|
||||
setup do
|
||||
ets_name = Kocaptcha.Ets
|
||||
^ets_name = :ets.new(ets_name, @ets_options)
|
||||
|
||||
mock(fn
|
||||
%{method: :get, url: "https://captcha.kotobank.ch/new"} ->
|
||||
json(%{
|
||||
md5: "63615261b77f5354fb8c4e4986477555",
|
||||
token: "afa1815e14e29355e6c8f6b143a39fa2",
|
||||
url: "/captchas/afa1815e14e29355e6c8f6b143a39fa2.png"
|
||||
})
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "new and validate" do
|
||||
assert Kocaptcha.new() == %{
|
||||
type: :kocaptcha,
|
||||
token: "afa1815e14e29355e6c8f6b143a39fa2",
|
||||
url: "https://captcha.kotobank.ch/captchas/afa1815e14e29355e6c8f6b143a39fa2.png"
|
||||
}
|
||||
|
||||
assert Kocaptcha.validate(
|
||||
"afa1815e14e29355e6c8f6b143a39fa2",
|
||||
"7oEy8c"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,100 @@
|
||||
defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.OAuth
|
||||
alias Pleroma.Integration.WebsocketClient
|
||||
alias Pleroma.Web.Streamer
|
||||
|
||||
@path Pleroma.Web.Endpoint.url()
|
||||
|> URI.parse()
|
||||
|> Map.put(:scheme, "ws")
|
||||
|> Map.put(:path, "/api/v1/streaming")
|
||||
|> URI.to_string()
|
||||
|
||||
setup do
|
||||
GenServer.start(Streamer, %{}, name: Streamer)
|
||||
|
||||
on_exit(fn ->
|
||||
if pid = Process.whereis(Streamer) do
|
||||
Process.exit(pid, :kill)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def start_socket(qs \\ nil, headers \\ []) do
|
||||
path =
|
||||
case qs do
|
||||
nil -> @path
|
||||
qs -> @path <> qs
|
||||
end
|
||||
|
||||
WebsocketClient.start_link(self(), path, headers)
|
||||
end
|
||||
|
||||
test "refuses invalid requests" do
|
||||
assert {:error, {400, _}} = start_socket()
|
||||
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
|
||||
end
|
||||
|
||||
test "requires authentication and a valid token for protected streams" do
|
||||
assert {:error, {403, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
||||
assert {:error, {403, _}} = start_socket("?stream=user")
|
||||
end
|
||||
|
||||
test "allows public streams without authentication" do
|
||||
assert {:ok, _} = start_socket("?stream=public")
|
||||
assert {:ok, _} = start_socket("?stream=public:local")
|
||||
assert {:ok, _} = start_socket("?stream=hashtag&tag=lain")
|
||||
end
|
||||
|
||||
test "receives well formatted events" do
|
||||
user = insert(:user)
|
||||
{:ok, _} = start_socket("?stream=public")
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "nice echo chamber"})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
assert {:ok, json} = Jason.decode(raw_json)
|
||||
|
||||
assert "update" == json["event"]
|
||||
assert json["payload"]
|
||||
assert {:ok, json} = Jason.decode(json["payload"])
|
||||
|
||||
# Note: we remove the "statuses_count" from this result as it changes in the meantime
|
||||
|
||||
view_json =
|
||||
Pleroma.Web.MastodonAPI.StatusView.render("status.json", activity: activity, for: nil)
|
||||
|> Jason.encode!()
|
||||
|> Jason.decode!()
|
||||
|> put_in(["account", "statuses_count"], 0)
|
||||
|
||||
assert json == view_json
|
||||
end
|
||||
|
||||
describe "with a valid user token" do
|
||||
setup do
|
||||
{:ok, app} =
|
||||
Pleroma.Repo.insert(
|
||||
OAuth.App.register_changeset(%OAuth.App{}, %{
|
||||
client_name: "client",
|
||||
scopes: "scope",
|
||||
redirect_uris: "url"
|
||||
})
|
||||
)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, auth} = OAuth.Authorization.create_authorization(app, user)
|
||||
|
||||
{:ok, token} = OAuth.Token.exchange_token(app, auth)
|
||||
|
||||
%{user: user, token: token}
|
||||
end
|
||||
|
||||
test "accepts valid tokens", state do
|
||||
assert {:ok, _} = start_socket("?stream=user&access_token=#{state.token.token}")
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,43 @@
|
||||
defmodule Pleroma.Web.RuntimeStaticPlugTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
@dir "test/tmp/instance_static"
|
||||
|
||||
setup do
|
||||
static_dir = Pleroma.Config.get([:instance, :static_dir])
|
||||
Pleroma.Config.put([:instance, :static_dir], @dir)
|
||||
File.mkdir_p!(@dir)
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put([:instance, :static_dir], static_dir)
|
||||
File.rm_rf(@dir)
|
||||
end)
|
||||
end
|
||||
|
||||
test "overrides index" do
|
||||
bundled_index = get(build_conn(), "/")
|
||||
assert html_response(bundled_index, 200) == File.read!("priv/static/index.html")
|
||||
|
||||
File.write!(@dir <> "/index.html", "hello world")
|
||||
|
||||
index = get(build_conn(), "/")
|
||||
assert html_response(index, 200) == "hello world"
|
||||
end
|
||||
|
||||
test "overrides any file in static/static" do
|
||||
bundled_index = get(build_conn(), "/static/terms-of-service.html")
|
||||
|
||||
assert html_response(bundled_index, 200) ==
|
||||
File.read!("priv/static/static/terms-of-service.html")
|
||||
|
||||
File.mkdir!(@dir <> "/static")
|
||||
File.write!(@dir <> "/static/terms-of-service.html", "plz be kind")
|
||||
|
||||
index = get(build_conn(), "/static/terms-of-service.html")
|
||||
assert html_response(index, 200) == "plz be kind"
|
||||
|
||||
File.write!(@dir <> "/static/kaniini.html", "<h1>rabbit hugs as a service</h1>")
|
||||
index = get(build_conn(), "/static/kaniini.html")
|
||||
assert html_response(index, 200) == "<h1>rabbit hugs as a service</h1>"
|
||||
end
|
||||
end
|
@ -0,0 +1,13 @@
|
||||
defmodule Pleroma.Captcha.Mock do
|
||||
alias Pleroma.Captcha.Service
|
||||
@behaviour Service
|
||||
|
||||
@impl Service
|
||||
def new(), do: %{type: :mock}
|
||||
|
||||
@impl Service
|
||||
def validate(_token, _captcha), do: true
|
||||
|
||||
@impl Service
|
||||
def cleanup(), do: :ok
|
||||
end
|
@ -0,0 +1,58 @@
|
||||
defmodule Pleroma.Integration.WebsocketClient do
|
||||
# https://github.com/phoenixframework/phoenix/blob/master/test/support/websocket_client.exs
|
||||
|
||||
@doc """
|
||||
Starts the WebSocket server for given ws URL. Received Socket.Message's
|
||||
are forwarded to the sender pid
|
||||
"""
|
||||
def start_link(sender, url, headers \\ []) do
|
||||
:crypto.start()
|
||||
:ssl.start()
|
||||
|
||||
:websocket_client.start_link(
|
||||
String.to_charlist(url),
|
||||
__MODULE__,
|
||||
[sender],
|
||||
extra_headers: headers
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Closes the socket
|
||||
"""
|
||||
def close(socket) do
|
||||
send(socket, :close)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Sends a low-level text message to the client.
|
||||
"""
|
||||
def send_text(server_pid, msg) do
|
||||
send(server_pid, {:text, msg})
|
||||
end
|
||||
|
||||
@doc false
|
||||
def init([sender], _conn_state) do
|
||||
{:ok, %{sender: sender}}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def websocket_handle(frame, _conn_state, state) do
|
||||
send(state.sender, frame)
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def websocket_info({:text, msg}, _conn_state, state) do
|
||||
{:reply, {:text, msg}, state}
|
||||
end
|
||||
|
||||
def websocket_info(:close, _conn_state, _state) do
|
||||
{:close, <<>>, "done"}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def websocket_terminate(_reason, _conn_state, _state) do
|
||||
:ok
|
||||
end
|
||||
end
|
@ -0,0 +1,65 @@
|
||||
defmodule Mix.Tasks.Pleroma.RelayTest do
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Web.ActivityPub.{ActivityPub, Relay, Utils}
|
||||
alias Pleroma.User
|
||||
use Pleroma.DataCase
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
||||
Mix.shell(Mix.Shell.Process)
|
||||
|
||||
on_exit(fn ->
|
||||
Mix.shell(Mix.Shell.IO)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "running follow" do
|
||||
test "relay is followed" do
|
||||
target_instance = "http://mastodon.example.org/users/admin"
|
||||
|
||||
Mix.Tasks.Pleroma.Relay.run(["follow", target_instance])
|
||||
|
||||
local_user = Relay.get_actor()
|
||||
assert local_user.ap_id =~ "/relay"
|
||||
|
||||
target_user = User.get_by_ap_id(target_instance)
|
||||
refute target_user.local
|
||||
|
||||
activity = Utils.fetch_latest_follow(local_user, target_user)
|
||||
assert activity.data["type"] == "Follow"
|
||||
assert activity.data["actor"] == local_user.ap_id
|
||||
assert activity.data["object"] == target_user.ap_id
|
||||
end
|
||||
end
|
||||
|
||||
describe "running unfollow" do
|
||||
test "relay is unfollowed" do
|
||||
target_instance = "http://mastodon.example.org/users/admin"
|
||||
|
||||
Mix.Tasks.Pleroma.Relay.run(["follow", target_instance])
|
||||
|
||||
%User{ap_id: follower_id} = local_user = Relay.get_actor()
|
||||
target_user = User.get_by_ap_id(target_instance)
|
||||
follow_activity = Utils.fetch_latest_follow(local_user, target_user)
|
||||
|
||||
Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance])
|
||||
|
||||
cancelled_activity = Activity.get_by_ap_id(follow_activity.data["id"])
|
||||
assert cancelled_activity.data["state"] == "cancelled"
|
||||
|
||||
[undo_activity] =
|
||||
ActivityPub.fetch_activities([], %{
|
||||
"type" => "Undo",
|
||||
"actor_id" => follower_id,
|
||||
"limit" => 1
|
||||
})
|
||||
|
||||
assert undo_activity.data["type"] == "Undo"
|
||||
assert undo_activity.data["actor"] == local_user.ap_id
|
||||
assert undo_activity.data["object"] == cancelled_activity.data
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,52 @@
|
||||
defmodule Mix.Tasks.Pleroma.UploadsTest do
|
||||
alias Pleroma.Upload
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Mock
|
||||
|
||||
setup_all do
|
||||
Mix.shell(Mix.Shell.Process)
|
||||
|
||||
on_exit(fn ->
|
||||
Mix.shell(Mix.Shell.IO)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "running migrate_local" do
|
||||
test "uploads migrated" do
|
||||
with_mock Upload,
|
||||
store: fn %Upload{name: _file, path: _path}, _opts -> {:ok, %{}} end do
|
||||
Mix.Tasks.Pleroma.Uploads.run(["migrate_local", "S3"])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "Migrating files from local"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
|
||||
assert %{"total_count" => total_count} =
|
||||
Regex.named_captures(~r"^Found (?<total_count>\d+) uploads$", message)
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
|
||||
# @logevery in Mix.Tasks.Pleroma.Uploads
|
||||
count =
|
||||
min(50, String.to_integer(total_count))
|
||||
|> to_string()
|
||||
|
||||
assert %{"count" => ^count, "total_count" => ^total_count} =
|
||||
Regex.named_captures(
|
||||
~r"^Uploaded (?<count>\d+)/(?<total_count>\d+) files$",
|
||||
message
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
test "nonexistent uploader" do
|
||||
assert_raise RuntimeError, ~r/The uploader .* is not an existing/, fn ->
|
||||
Mix.Tasks.Pleroma.Uploads.run(["migrate_local", "nonexistent"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,247 @@
|
||||
defmodule Mix.Tasks.Pleroma.UserTest do
|
||||
alias Pleroma.User
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
import ExUnit.CaptureIO
|
||||
|
||||
setup_all do
|
||||
Mix.shell(Mix.Shell.Process)
|
||||
|
||||
on_exit(fn ->
|
||||
Mix.shell(Mix.Shell.IO)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "running new" do
|
||||
test "user is created" do
|
||||
# just get random data
|
||||
unsaved = build(:user)
|
||||
|
||||
# prepare to answer yes
|
||||
send(self(), {:mix_shell_input, :yes?, true})
|
||||
|
||||
Mix.Tasks.Pleroma.User.run([
|
||||
"new",
|
||||
unsaved.nickname,
|
||||
unsaved.email,
|
||||
"--name",
|
||||
unsaved.name,
|
||||
"--bio",
|
||||
unsaved.bio,
|
||||
"--password",
|
||||
"test",
|
||||
"--moderator",
|
||||
"--admin"
|
||||
])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "user will be created"
|
||||
|
||||
assert_received {:mix_shell, :yes?, [message]}
|
||||
assert message =~ "Continue"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "created"
|
||||
|
||||
user = User.get_by_nickname(unsaved.nickname)
|
||||
assert user.name == unsaved.name
|
||||
assert user.email == unsaved.email
|
||||
assert user.bio == unsaved.bio
|
||||
assert user.info.is_moderator
|
||||
assert user.info.is_admin
|
||||
end
|
||||
|
||||
test "user is not created" do
|
||||
unsaved = build(:user)
|
||||
|
||||
# prepare to answer no
|
||||
send(self(), {:mix_shell_input, :yes?, false})
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["new", unsaved.nickname, unsaved.email])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "user will be created"
|
||||
|
||||
assert_received {:mix_shell, :yes?, [message]}
|
||||
assert message =~ "Continue"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "will not be created"
|
||||
|
||||
refute User.get_by_nickname(unsaved.nickname)
|
||||
end
|
||||
end
|
||||
|
||||
describe "running rm" do
|
||||
test "user is deleted" do
|
||||
user = insert(:user)
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["rm", user.nickname])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ " deleted"
|
||||
|
||||
user = User.get_by_nickname(user.nickname)
|
||||
assert user.info.deactivated
|
||||
end
|
||||
|
||||
test "no user to delete" do
|
||||
Mix.Tasks.Pleroma.User.run(["rm", "nonexistent"])
|
||||
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "No local user"
|
||||
end
|
||||
end
|
||||
|
||||
describe "running toggle_activated" do
|
||||
test "user is deactivated" do
|
||||
user = insert(:user)
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["toggle_activated", user.nickname])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ " deactivated"
|
||||
|
||||
user = User.get_by_nickname(user.nickname)
|
||||
assert user.info.deactivated
|
||||
end
|
||||
|
||||
test "user is activated" do
|
||||
user = insert(:user, info: %{deactivated: true})
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["toggle_activated", user.nickname])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ " activated"
|
||||
|
||||
user = User.get_by_nickname(user.nickname)
|
||||
refute user.info.deactivated
|
||||
end
|
||||
|
||||
test "no user to toggle" do
|
||||
Mix.Tasks.Pleroma.User.run(["toggle_activated", "nonexistent"])
|
||||
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "No user"
|
||||
end
|
||||
end
|
||||
|
||||
describe "running unsubscribe" do
|
||||
test "user is unsubscribed" do
|
||||
followed = insert(:user)
|
||||
user = insert(:user, %{following: [User.ap_followers(followed)]})
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["unsubscribe", user.nickname])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "Deactivating"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "Unsubscribing"
|
||||
|
||||
# Note that the task has delay :timer.sleep(500)
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "Successfully unsubscribed"
|
||||
|
||||
user = User.get_by_nickname(user.nickname)
|
||||
assert length(user.following) == 0
|
||||
assert user.info.deactivated
|
||||
end
|
||||
|
||||
test "no user to unsubscribe" do
|
||||
Mix.Tasks.Pleroma.User.run(["unsubscribe", "nonexistent"])
|
||||
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "No user"
|
||||
end
|
||||
end
|
||||
|
||||
describe "running set" do
|
||||
test "All statuses set" do
|
||||
user = insert(:user)
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["set", user.nickname, "--moderator", "--admin", "--locked"])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ ~r/Moderator status .* true/
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ ~r/Locked status .* true/
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ ~r/Admin status .* true/
|
||||
|
||||
user = User.get_by_nickname(user.nickname)
|
||||
assert user.info.is_moderator
|
||||
assert user.info.locked
|
||||
assert user.info.is_admin
|
||||
end
|
||||
|
||||
test "All statuses unset" do
|
||||
user = insert(:user, info: %{is_moderator: true, locked: true, is_admin: true})
|
||||
|
||||
Mix.Tasks.Pleroma.User.run([
|
||||
"set",
|
||||
user.nickname,
|
||||
"--no-moderator",
|
||||
"--no-admin",
|
||||
"--no-locked"
|
||||
])
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ ~r/Moderator status .* false/
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ ~r/Locked status .* false/
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ ~r/Admin status .* false/
|
||||
|
||||
user = User.get_by_nickname(user.nickname)
|
||||
refute user.info.is_moderator
|
||||
refute user.info.locked
|
||||
refute user.info.is_admin
|
||||
end
|
||||
|
||||
test "no user to set status" do
|
||||
Mix.Tasks.Pleroma.User.run(["set", "nonexistent", "--moderator"])
|
||||
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "No local user"
|
||||
end
|
||||
end
|
||||
|
||||
describe "running reset_password" do
|
||||
test "password reset token is generated" do
|
||||
user = insert(:user)
|
||||
|
||||
assert capture_io(fn ->
|
||||
Mix.Tasks.Pleroma.User.run(["reset_password", user.nickname])
|
||||
end) =~ "URL:"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "Generated"
|
||||
end
|
||||
|
||||
test "no user to reset password" do
|
||||
Mix.Tasks.Pleroma.User.run(["reset_password", "nonexistent"])
|
||||
|
||||
assert_received {:mix_shell, :error, [message]}
|
||||
assert message =~ "No local user"
|
||||
end
|
||||
end
|
||||
|
||||
describe "running invite" do
|
||||
test "invite token is generated" do
|
||||
assert capture_io(fn ->
|
||||
Mix.Tasks.Pleroma.User.run(["invite"])
|
||||
end) =~ "http"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ "Generated"
|
||||
end
|
||||
end
|
||||
end
|
@ -1,31 +0,0 @@
|
||||
defmodule Pleroma.Web.MastodonApi.MastodonSocketTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.{Streamer, CommonAPI}
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "public is working when non-authenticated" do
|
||||
user = insert(:user)
|
||||
|
||||
task =
|
||||
Task.async(fn ->
|
||||
assert_receive {:text, _}, 4_000
|
||||
end)
|
||||
|
||||
fake_socket = %{
|
||||
transport_pid: task.pid,
|
||||
assigns: %{}
|
||||
}
|
||||
|
||||
topics = %{
|
||||
"public" => [fake_socket]
|
||||
}
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "Test"})
|
||||
|
||||
Streamer.push_to_socket(topics, "public", activity)
|
||||
|
||||
Task.await(task)
|
||||
end
|
||||
end
|
Loading…
Reference in new issue