Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop
This commit is contained in:
commit
6f5844cf8e
10 changed files with 96 additions and 26 deletions
|
@ -84,6 +84,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- ActivityPub: Configurable `type` field of the actors.
|
- ActivityPub: Configurable `type` field of the actors.
|
||||||
- Mastodon API: `/api/v1/accounts/:id` has `source/pleroma/actor_type` field.
|
- Mastodon API: `/api/v1/accounts/:id` has `source/pleroma/actor_type` field.
|
||||||
- Mastodon API: `/api/v1/update_credentials` accepts `actor_type` field.
|
- Mastodon API: `/api/v1/update_credentials` accepts `actor_type` field.
|
||||||
|
- Captcha: Support native provider
|
||||||
|
- Captcha: Enable by default
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -66,9 +66,9 @@
|
||||||
jobs: scheduled_jobs
|
jobs: scheduled_jobs
|
||||||
|
|
||||||
config :pleroma, Pleroma.Captcha,
|
config :pleroma, Pleroma.Captcha,
|
||||||
enabled: false,
|
enabled: true,
|
||||||
seconds_valid: 60,
|
seconds_valid: 60,
|
||||||
method: Pleroma.Captcha.Kocaptcha
|
method: Pleroma.Captcha.Native
|
||||||
|
|
||||||
config :pleroma, :hackney_pools,
|
config :pleroma, :hackney_pools,
|
||||||
federation: [
|
federation: [
|
||||||
|
@ -84,8 +84,6 @@
|
||||||
timeout: 300_000
|
timeout: 300_000
|
||||||
]
|
]
|
||||||
|
|
||||||
config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "https://captcha.kotobank.ch"
|
|
||||||
|
|
||||||
# Upload configuration
|
# Upload configuration
|
||||||
config :pleroma, Pleroma.Upload,
|
config :pleroma, Pleroma.Upload,
|
||||||
uploader: Pleroma.Uploaders.Local,
|
uploader: Pleroma.Uploaders.Local,
|
||||||
|
|
|
@ -95,6 +95,8 @@
|
||||||
|
|
||||||
config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock
|
config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock
|
||||||
|
|
||||||
|
config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "https://captcha.kotobank.ch"
|
||||||
|
|
||||||
if File.exists?("./config/test.secret.exs") do
|
if File.exists?("./config/test.secret.exs") do
|
||||||
import_config "test.secret.exs"
|
import_config "test.secret.exs"
|
||||||
else
|
else
|
||||||
|
|
|
@ -379,13 +379,19 @@ For each pool, the options are:
|
||||||
## Captcha
|
## Captcha
|
||||||
|
|
||||||
### Pleroma.Captcha
|
### Pleroma.Captcha
|
||||||
|
|
||||||
* `enabled`: Whether the captcha should be shown on registration.
|
* `enabled`: Whether the captcha should be shown on registration.
|
||||||
* `method`: The method/service to use for captcha.
|
* `method`: The method/service to use for captcha.
|
||||||
* `seconds_valid`: The time in seconds for which the captcha is valid.
|
* `seconds_valid`: The time in seconds for which the captcha is valid.
|
||||||
|
|
||||||
### Captcha providers
|
### Captcha providers
|
||||||
|
|
||||||
|
#### Pleroma.Captcha.Native
|
||||||
|
|
||||||
|
A built-in captcha provider. Enabled by default.
|
||||||
|
|
||||||
#### Pleroma.Captcha.Kocaptcha
|
#### Pleroma.Captcha.Kocaptcha
|
||||||
|
|
||||||
Kocaptcha is a very simple captcha service with a single API endpoint,
|
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
|
the source code is here: https://github.com/koto-bank/kocaptcha. The default endpoint
|
||||||
`https://captcha.kotobank.ch` is hosted by the developer.
|
`https://captcha.kotobank.ch` is hosted by the developer.
|
||||||
|
|
35
lib/pleroma/captcha/native.ex
Normal file
35
lib/pleroma/captcha/native.ex
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Captcha.Native do
|
||||||
|
import Pleroma.Web.Gettext
|
||||||
|
alias Pleroma.Captcha.Service
|
||||||
|
@behaviour Service
|
||||||
|
|
||||||
|
@impl Service
|
||||||
|
def new do
|
||||||
|
case Captcha.get() do
|
||||||
|
{:timeout} ->
|
||||||
|
%{error: dgettext("errors", "Captcha timeout")}
|
||||||
|
|
||||||
|
{:ok, answer_data, img_binary} ->
|
||||||
|
%{
|
||||||
|
type: :native,
|
||||||
|
token: token(),
|
||||||
|
url: "data:image/png;base64," <> Base.encode64(img_binary),
|
||||||
|
answer_data: answer_data
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl Service
|
||||||
|
def validate(_token, captcha, captcha) when not is_nil(captcha), do: :ok
|
||||||
|
def validate(_token, _captcha, _answer), do: {:error, dgettext("errors", "Invalid CAPTCHA")}
|
||||||
|
|
||||||
|
defp token do
|
||||||
|
10
|
||||||
|
|> :crypto.strong_rand_bytes()
|
||||||
|
|> Base.url_encode64(padding: false)
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
||||||
alias Pleroma.HTTP
|
alias Pleroma.HTTP
|
||||||
alias Pleroma.Instances
|
alias Pleroma.Instances
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.Relay
|
alias Pleroma.Web.ActivityPub.Relay
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
@ -188,31 +189,35 @@ def publish(%User{} = actor, %{data: %{"bcc" => bcc}} = activity)
|
||||||
|
|
||||||
recipients = recipients(actor, activity)
|
recipients = recipients(actor, activity)
|
||||||
|
|
||||||
recipients
|
inboxes =
|
||||||
|> Enum.filter(&User.ap_enabled?/1)
|
recipients
|
||||||
|> Enum.map(fn %{source_data: data} -> data["inbox"] end)
|
|> Enum.filter(&User.ap_enabled?/1)
|
||||||
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
|> Enum.map(fn %{source_data: data} -> data["inbox"] end)
|
||||||
|> Instances.filter_reachable()
|
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
||||||
|> Enum.each(fn {inbox, unreachable_since} ->
|
|> Instances.filter_reachable()
|
||||||
%User{ap_id: ap_id} =
|
|
||||||
Enum.find(recipients, fn %{source_data: data} -> data["inbox"] == inbox end)
|
|
||||||
|
|
||||||
# Get all the recipients on the same host and add them to cc. Otherwise, a remote
|
Repo.checkout(fn ->
|
||||||
# instance would only accept a first message for the first recipient and ignore the rest.
|
Enum.each(inboxes, fn {inbox, unreachable_since} ->
|
||||||
cc = get_cc_ap_ids(ap_id, recipients)
|
%User{ap_id: ap_id} =
|
||||||
|
Enum.find(recipients, fn %{source_data: data} -> data["inbox"] == inbox end)
|
||||||
|
|
||||||
json =
|
# Get all the recipients on the same host and add them to cc. Otherwise, a remote
|
||||||
data
|
# instance would only accept a first message for the first recipient and ignore the rest.
|
||||||
|> Map.put("cc", cc)
|
cc = get_cc_ap_ids(ap_id, recipients)
|
||||||
|> Jason.encode!()
|
|
||||||
|
|
||||||
Pleroma.Web.Federator.Publisher.enqueue_one(__MODULE__, %{
|
json =
|
||||||
inbox: inbox,
|
data
|
||||||
json: json,
|
|> Map.put("cc", cc)
|
||||||
actor_id: actor.id,
|
|> Jason.encode!()
|
||||||
id: activity.data["id"],
|
|
||||||
unreachable_since: unreachable_since
|
Pleroma.Web.Federator.Publisher.enqueue_one(__MODULE__, %{
|
||||||
})
|
inbox: inbox,
|
||||||
|
json: json,
|
||||||
|
actor_id: actor.id,
|
||||||
|
id: activity.data["id"],
|
||||||
|
unreachable_since: unreachable_since
|
||||||
|
})
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
3
mix.exs
3
mix.exs
|
@ -163,6 +163,9 @@ defp deps do
|
||||||
{:remote_ip,
|
{:remote_ip,
|
||||||
git: "https://git.pleroma.social/pleroma/remote_ip.git",
|
git: "https://git.pleroma.social/pleroma/remote_ip.git",
|
||||||
ref: "825dc00aaba5a1b7c4202a532b696b595dd3bcb3"},
|
ref: "825dc00aaba5a1b7c4202a532b696b595dd3bcb3"},
|
||||||
|
{:captcha,
|
||||||
|
git: "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git",
|
||||||
|
ref: "c3c795c55f6b49d79d6ac70a0f91e525099fc3e2"},
|
||||||
{:mox, "~> 0.5", only: :test}
|
{:mox, "~> 0.5", only: :test}
|
||||||
] ++ oauth_deps()
|
] ++ oauth_deps()
|
||||||
end
|
end
|
||||||
|
|
1
mix.lock
1
mix.lock
|
@ -8,6 +8,7 @@
|
||||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
|
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
|
||||||
"cachex": {:hex, :cachex, "3.0.3", "4e2d3e05814a5738f5ff3903151d5c25636d72a3527251b753f501ad9c657967", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm"},
|
"cachex": {:hex, :cachex, "3.0.3", "4e2d3e05814a5738f5ff3903151d5c25636d72a3527251b753f501ad9c657967", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"calendar": {:hex, :calendar, "0.17.6", "ec291cb2e4ba499c2e8c0ef5f4ace974e2f9d02ae9e807e711a9b0c7850b9aee", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
|
"calendar": {:hex, :calendar, "0.17.6", "ec291cb2e4ba499c2e8c0ef5f4ace974e2f9d02ae9e807e711a9b0c7850b9aee", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "c3c795c55f6b49d79d6ac70a0f91e525099fc3e2", [ref: "c3c795c55f6b49d79d6ac70a0f91e525099fc3e2"]},
|
||||||
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
|
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
|
||||||
"comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"},
|
"comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
|
|
0
priv/static/static/font/fontello.1576166651574.svg
Normal file → Executable file
0
priv/static/static/font/fontello.1576166651574.svg
Normal file → Executable file
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -8,6 +8,7 @@ defmodule Pleroma.CaptchaTest do
|
||||||
import Tesla.Mock
|
import Tesla.Mock
|
||||||
|
|
||||||
alias Pleroma.Captcha.Kocaptcha
|
alias Pleroma.Captcha.Kocaptcha
|
||||||
|
alias Pleroma.Captcha.Native
|
||||||
|
|
||||||
@ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
|
@ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
|
||||||
|
|
||||||
|
@ -43,4 +44,21 @@ test "new and validate" do
|
||||||
) == :ok
|
) == :ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Native" do
|
||||||
|
test "new and validate" do
|
||||||
|
new = Native.new()
|
||||||
|
|
||||||
|
assert %{
|
||||||
|
answer_data: answer,
|
||||||
|
token: token,
|
||||||
|
type: :native,
|
||||||
|
url: "data:image/png;base64," <> _
|
||||||
|
} = new
|
||||||
|
|
||||||
|
assert is_binary(answer)
|
||||||
|
assert :ok = Native.validate(token, answer, answer)
|
||||||
|
assert {:error, "Invalid CAPTCHA"} == Native.validate(token, answer, answer <> "foobar")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue