Commit ef318fb8 authored by rinpatch's avatar rinpatch
Browse files

Merge branch 'develop' into fix/formatter-ignore-html-chars

parents 059dd6f6 443d59ba
......@@ -8,7 +8,9 @@
/.elixir_ls
/test/fixtures/test_tmp.txt
/test/fixtures/image_tmp.jpg
/test/tmp/
/doc
/instance
# Prevent committing custom emojis
/priv/static/emoji/custom/*
......@@ -31,4 +33,4 @@ erl_crash.dump
.env
# Editor config
/.vscode
/.vscode/
......@@ -13,7 +13,6 @@ cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- deps
- _build
stages:
- lint
- test
......
......@@ -10,6 +10,13 @@
config :pleroma, Pleroma.Repo, types: Pleroma.PostgresTypes
config :pleroma, Pleroma.Captcha,
enabled: false,
seconds_retained: 180,
method: Pleroma.Captcha.Kocaptcha
config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "https://captcha.kotobank.ch"
# Upload configuration
config :pleroma, Pleroma.Upload,
uploader: Pleroma.Uploaders.Local,
......@@ -50,6 +57,15 @@
# Configures the endpoint
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "localhost"],
http: [
dispatch: [
{:_,
[
{"/api/v1/streaming", Elixir.Pleroma.Web.MastodonAPI.WebsocketHandler, []},
{:_, Plug.Adapters.Cowboy.Handler, {Pleroma.Web.Endpoint, []}}
]}
]
],
protocol: "https",
secret_key_base: "aK4Abxf29xU9TTDKre9coZPUgevcVCFQJe/5xP/7Lt4BEif6idBIbjupVbOrbKxl",
signing_salt: "CqaoopA2",
......@@ -94,6 +110,7 @@
public: true,
quarantined_instances: [],
managed_config: true,
static_dir: "instance/static/",
allowed_post_formats: [
"text/plain",
"text/html",
......@@ -120,8 +137,8 @@
logo_mask: true,
logo_margin: "0.1em",
background: "/static/aurora_borealis.jpg",
redirect_root_no_login: "/main/all",
redirect_root_login: "/main/friends",
redirect_root_no_login: "/~/main/all",
redirect_root_login: "/~/main/friends",
show_instance_panel: true,
scope_options_enabled: false,
formatting_options_enabled: false,
......
......@@ -7,7 +7,7 @@ If you run Pleroma with ``MIX_ENV=prod`` the file is ``prod.secret.exs``, otherw
* `uploader`: Select which `Pleroma.Uploaders` to use
* `filters`: List of `Pleroma.Upload.Filter` to use.
* `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host.
* `proxy_remote`: If you're using a remote uploader, Pleroma will proxy media requests instead of redirecting to it.
* `proxy_remote`: If you\'re using a remote uploader, Pleroma will proxy media requests instead of redirecting to it.
* `proxy_opts`: Proxy options, see `Pleroma.ReverseProxy` documentation.
Note: `strip_exif` has been replaced by `Pleroma.Upload.Filter.Mogrify`.
......@@ -163,3 +163,15 @@ Web Push Notifications configuration. You can use the mix task `mix web_push.gen
* ``subject``: a mailto link for the administrative contact. It’s best if this email is not a personal email address, but rather a group email so that if a person leaves an organization, is unavailable for an extended period, or otherwise can’t respond, someone else on the list can.
* ``public_key``: VAPID public key
* ``private_key``: VAPID private key
## Pleroma.Captcha
* `enabled`: Whether the captcha should be shown on registration
* `method`: The method/service to use for captcha
* `seconds_retained`: The time in seconds for which the captcha is valid (stored in the cache)
### Pleroma.Captcha.Kocaptcha
Kocaptcha is a very simple captcha service with a single API endpoint,
the source code is here: https://github.com/koto-bank/kocaptcha. The default endpoint
`https://captcha.kotobank.ch` is hosted by the developer.
* `endpoint`: the kocaptcha endpoint to use
\ No newline at end of file
......@@ -12,6 +12,7 @@
protocol_options: [max_request_line_length: 8192, max_header_value_length: 8192]
],
protocol: "http",
secure_cookie_flag: false,
debug_errors: true,
code_reloader: true,
check_origin: false,
......
......@@ -4,7 +4,14 @@
# you can enable the server option below.
config :pleroma, Pleroma.Web.Endpoint,
http: [port: 4001],
server: false
url: [port: 4001],
server: true
# Disable captha for tests
config :pleroma, Pleroma.Captcha,
enabled: true,
# A fake captcha service for tests
method: Pleroma.Captcha.Mock
# Print only warnings and errors during test
config :logger, level: :warn
......
#!/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
#
# 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"
}
#!/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
#
# 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
}
CREATE USER pleroma WITH ENCRYPTED PASSWORD '<%= dbpass %>';
CREATE DATABASE pleroma_dev OWNER pleroma;
\c pleroma_dev;
CREATE USER <%= dbuser %> WITH ENCRYPTED PASSWORD '<%= dbpass %>';
CREATE DATABASE <%= dbname %> OWNER <%= dbuser %>;
\c <%= dbname %>;
--Extensions made by ecto.migrate that need superuser access
CREATE EXTENSION IF NOT EXISTS citext;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
......
......@@ -94,16 +94,14 @@ def run(["new", nickname, email | rest]) do
unless not proceed? do
Common.start_pleroma()
params =
%{
nickname: nickname,
email: email,
password: password,
password_confirmation: password,
name: name,
bio: bio
}
|> IO.inspect()
params = %{
nickname: nickname,
email: email,
password: password,
password_confirmation: password,
name: name,
bio: bio
}
user = User.register_changeset(%User{}, params)
Repo.insert!(user)
......
......@@ -24,6 +24,7 @@ def start(_type, _args) do
# Start the Ecto repository
supervisor(Pleroma.Repo, []),
worker(Pleroma.Emoji, []),
worker(Pleroma.Captcha, []),
worker(
Cachex,
[
......
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
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
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
......@@ -11,7 +11,8 @@ def call(conn, _opts) do
else
conn
|> put_status(404)
|> Phoenix.Controller.render(Pleroma.Web.ErrorView, "404.json")
|> Phoenix.Controller.put_view(Pleroma.Web.ErrorView)
|> Phoenix.Controller.render("404.json")
|> halt()
end
end
......
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
......@@ -838,7 +838,7 @@ def tag(nickname, tags) when is_binary(nickname),
do: tag(User.get_by_nickname(nickname), tags)
def tag(%User{} = user, tags),
do: update_tags(user, Enum.uniq(user.tags ++ normalize_tags(tags)))
do: update_tags(user, Enum.uniq((user.tags || []) ++ normalize_tags(tags)))
def untag(user_identifiers, tags) when is_list(user_identifiers) do
Repo.transaction(fn ->
......@@ -849,7 +849,8 @@ def untag(user_identifiers, tags) when is_list(user_identifiers) do
def untag(nickname, tags) when is_binary(nickname),
do: untag(User.get_by_nickname(nickname), tags)
def untag(%User{} = user, tags), do: update_tags(user, user.tags -- normalize_tags(tags))
def untag(%User{} = user, tags),
do: update_tags(user, (user.tags || []) -- normalize_tags(tags))
defp update_tags(%User{} = user, new_tags) do
{:ok, updated_user} =
......
......@@ -149,9 +149,12 @@ def mastodon_profile_update(info, params) do
])
end
def mastodon_settings_update(info, params) do
def mastodon_settings_update(info, settings) do
params = %{settings: settings}
info
|> cast(params, [:settings])
|> validate_required([:settings])
end
def set_source_data(info, source_data) do
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment