Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
24 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/pleroma/emails/admin_email.ex b/lib/pleroma/emails/admin_email.ex
index aa0b2a66b..fae7faf00 100644
--- a/lib/pleroma/emails/admin_email.ex
+++ b/lib/pleroma/emails/admin_email.ex
@@ -1,85 +1,99 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emails.AdminEmail do
@moduledoc "Admin emails"
import Swoosh.Email
alias Pleroma.Config
alias Pleroma.Web.Router.Helpers
defp instance_config, do: Config.get(:instance)
defp instance_name, do: instance_config()[:name]
defp instance_notify_email do
Keyword.get(instance_config(), :notify_email, instance_config()[:email])
end
defp user_url(user) do
Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, user.id)
end
def test_email(mail_to \\ nil) do
html_body = """
<h3>Instance Test Email</h3>
<p>A test email was requested. Hello. :)</p>
"""
new()
|> to(mail_to || Config.get([:instance, :email]))
|> from({instance_name(), instance_notify_email()})
|> subject("Instance Test Email")
|> html_body(html_body)
end
def report(to, reporter, account, statuses, comment) do
comment_html =
if comment do
"<p>Comment: #{comment}"
else
""
end
statuses_html =
if is_list(statuses) && length(statuses) > 0 do
statuses_list_html =
statuses
|> Enum.map(fn
%{id: id} ->
status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, id)
"<li><a href=\"#{status_url}\">#{status_url}</li>"
id when is_binary(id) ->
"<li><a href=\"#{id}\">#{id}</li>"
end)
|> Enum.join("\n")
"""
<p> Statuses:
<ul>
#{statuses_list_html}
</ul>
</p>
"""
else
""
end
html_body = """
<p>Reported by: <a href="#{user_url(reporter)}">#{reporter.nickname}</a></p>
<p>Reported Account: <a href="#{user_url(account)}">#{account.nickname}</a></p>
#{comment_html}
#{statuses_html}
<p>
<a href="#{Pleroma.Web.base_url()}/pleroma/admin/#/reports/index">View Reports in AdminFE</a>
"""
new()
|> to({to.name, to.email})
|> from({instance_name(), instance_notify_email()})
|> subject("#{instance_name()} Report")
|> html_body(html_body)
end
+
+ def new_unapproved_registration(to, account) do
+ html_body = """
+ <p>New account for review: <a href="#{user_url(account)}">@#{account.nickname}</a></p>
+ <blockquote>#{account.registration_reason}</blockquote>
+ <a href="#{Pleroma.Web.base_url()}/pleroma/admin">Visit AdminFE</a>
+ """
+
+ new()
+ |> to({to.name, to.email})
+ |> from({instance_name(), instance_notify_email()})
+ |> subject("New account up for review on #{instance_name()} (@#{account.nickname})")
+ |> html_body(html_body)
+ end
end
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 4ff021b82..2294d9d0d 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -1,138 +1,151 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
import Pleroma.Web.Gettext
alias Pleroma.Emails.Mailer
alias Pleroma.Emails.UserEmail
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.UserInviteToken
def register_user(params, opts \\ []) do
params =
params
|> Map.take([:email, :token, :password])
|> Map.put(:bio, params |> Map.get(:bio, "") |> User.parse_bio())
|> Map.put(:nickname, params[:username])
|> Map.put(:name, Map.get(params, :fullname, params[:username]))
|> Map.put(:password_confirmation, params[:password])
|> Map.put(:registration_reason, params[:reason])
if Pleroma.Config.get([:instance, :registrations_open]) do
create_user(params, opts)
else
create_user_with_invite(params, opts)
end
end
defp create_user_with_invite(params, opts) do
with %{token: token} when is_binary(token) <- params,
%UserInviteToken{} = invite <- Repo.get_by(UserInviteToken, %{token: token}),
true <- UserInviteToken.valid_invite?(invite) do
UserInviteToken.update_usage!(invite)
create_user(params, opts)
else
nil -> {:error, "Invalid token"}
_ -> {:error, "Expired token"}
end
end
defp create_user(params, opts) do
changeset = User.register_changeset(%User{}, params, opts)
case User.register(changeset) do
{:ok, user} ->
+ maybe_notify_admins(user)
{:ok, user}
{:error, changeset} ->
errors =
changeset
|> Ecto.Changeset.traverse_errors(fn {msg, _opts} -> msg end)
|> Jason.encode!()
{:error, errors}
end
end
+ defp maybe_notify_admins(%User{} = account) do
+ if Pleroma.Config.get([:instance, :account_approval_required]) do
+ User.all_superusers()
+ |> Enum.filter(fn user -> not is_nil(user.email) end)
+ |> Enum.each(fn superuser ->
+ superuser
+ |> Pleroma.Emails.AdminEmail.new_unapproved_registration(account)
+ |> Pleroma.Emails.Mailer.deliver_async()
+ end)
+ end
+ end
+
def password_reset(nickname_or_email) do
with true <- is_binary(nickname_or_email),
%User{local: true, email: email} = user when is_binary(email) <-
User.get_by_nickname_or_email(nickname_or_email),
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
user
|> UserEmail.password_reset_email(token_record.token)
|> Mailer.deliver_async()
{:ok, :enqueued}
else
false ->
{:error, "bad user identifier"}
%User{local: true, email: nil} ->
{:ok, :noop}
%User{local: false} ->
{:error, "remote user"}
nil ->
{:error, "unknown user"}
end
end
def validate_captcha(app, params) do
if app.trusted || not Pleroma.Captcha.enabled?() do
:ok
else
do_validate_captcha(params)
end
end
defp do_validate_captcha(params) do
with :ok <- validate_captcha_presence(params),
:ok <-
Pleroma.Captcha.validate(
params[:captcha_token],
params[:captcha_solution],
params[:captcha_answer_data]
) do
:ok
else
{:error, :captcha_error} ->
captcha_error(dgettext("errors", "CAPTCHA Error"))
{:error, :invalid} ->
captcha_error(dgettext("errors", "Invalid CAPTCHA"))
{:error, :kocaptcha_service_unavailable} ->
captcha_error(dgettext("errors", "Kocaptcha service unavailable"))
{:error, :expired} ->
captcha_error(dgettext("errors", "CAPTCHA expired"))
{:error, :already_used} ->
captcha_error(dgettext("errors", "CAPTCHA already used"))
{:error, :invalid_answer_data} ->
captcha_error(dgettext("errors", "Invalid answer data"))
{:error, error} ->
captcha_error(error)
end
end
defp validate_captcha_presence(params) do
[:captcha_solution, :captcha_token, :captcha_answer_data]
|> Enum.find_value(:ok, fn key ->
unless is_binary(params[key]) do
error = dgettext("errors", "Invalid CAPTCHA (Missing parameter: %{name})", name: key)
{:error, error}
end
end)
end
# For some reason FE expects error message to be a serialized JSON
defp captcha_error(error), do: {:error, Jason.encode!(%{captcha: [error]})}
end
diff --git a/test/emails/admin_email_test.exs b/test/emails/admin_email_test.exs
index 9082ae5a7..e24231e27 100644
--- a/test/emails/admin_email_test.exs
+++ b/test/emails/admin_email_test.exs
@@ -1,49 +1,69 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emails.AdminEmailTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Emails.AdminEmail
alias Pleroma.Web.Router.Helpers
test "build report email" do
config = Pleroma.Config.get(:instance)
to_user = insert(:user)
reporter = insert(:user)
account = insert(:user)
res =
AdminEmail.report(to_user, reporter, account, [%{name: "Test", id: "12"}], "Test comment")
status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, "12")
reporter_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.id)
account_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
assert res.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_email]}
assert res.subject == "#{config[:name]} Report"
assert res.html_body ==
"<p>Reported by: <a href=\"#{reporter_url}\">#{reporter.nickname}</a></p>\n<p>Reported Account: <a href=\"#{
account_url
}\">#{account.nickname}</a></p>\n<p>Comment: Test comment\n<p> Statuses:\n <ul>\n <li><a href=\"#{
status_url
}\">#{status_url}</li>\n </ul>\n</p>\n\n<p>\n<a href=\"http://localhost:4001/pleroma/admin/#/reports/index\">View Reports in AdminFE</a>\n"
end
test "it works when the reporter is a remote user without email" do
config = Pleroma.Config.get(:instance)
to_user = insert(:user)
reporter = insert(:user, email: nil, local: false)
account = insert(:user)
res =
AdminEmail.report(to_user, reporter, account, [%{name: "Test", id: "12"}], "Test comment")
assert res.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_email]}
end
+
+ test "new unapproved registration email" do
+ config = Pleroma.Config.get(:instance)
+ to_user = insert(:user)
+ account = insert(:user, registration_reason: "Plz let me in")
+
+ res = AdminEmail.new_unapproved_registration(to_user, account)
+
+ account_url = Helpers.user_feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
+
+ assert res.to == [{to_user.name, to_user.email}]
+ assert res.from == {config[:name], config[:notify_email]}
+ assert res.subject == "New account up for review on #{config[:name]} (@#{account.nickname})"
+
+ assert res.html_body == """
+ <p>New account for review: <a href="#{account_url}">@#{account.nickname}</a></p>
+ <blockquote>Plz let me in</blockquote>
+ <a href="http://localhost:4001/pleroma/admin">Visit AdminFE</a>
+ """
+ end
end
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index 368533292..df9d59f6a 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -1,415 +1,452 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
+ import Pleroma.Factory
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.UserInviteToken
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.TwitterAPI.TwitterAPI
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
test "it registers a new user and returns the user." do
data = %{
:username => "lain",
:email => "lain@wired.jp",
:fullname => "lain iwakura",
:password => "bear",
:confirm => "bear"
}
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("lain")
assert AccountView.render("show.json", %{user: user}) ==
AccountView.render("show.json", %{user: fetched_user})
end
test "it registers a new user with empty string in bio and returns the user." do
data = %{
:username => "lain",
:email => "lain@wired.jp",
:fullname => "lain iwakura",
:bio => "",
:password => "bear",
:confirm => "bear"
}
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("lain")
assert AccountView.render("show.json", %{user: user}) ==
AccountView.render("show.json", %{user: fetched_user})
end
test "it sends confirmation email if :account_activation_required is specified in instance config" do
setting = Pleroma.Config.get([:instance, :account_activation_required])
unless setting do
Pleroma.Config.put([:instance, :account_activation_required], true)
on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
end
data = %{
:username => "lain",
:email => "lain@wired.jp",
:fullname => "lain iwakura",
:bio => "",
:password => "bear",
:confirm => "bear"
}
{:ok, user} = TwitterAPI.register_user(data)
ObanHelpers.perform_all()
assert user.confirmation_pending
email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
notify_email = Pleroma.Config.get([:instance, :notify_email])
instance_name = Pleroma.Config.get([:instance, :name])
Swoosh.TestAssertions.assert_email_sent(
from: {instance_name, notify_email},
to: {user.name, user.email},
html_body: email.html_body
)
end
+ test "it sends an admin email if :account_approval_required is specified in instance config" do
+ admin = insert(:user, is_admin: true)
+ setting = Pleroma.Config.get([:instance, :account_approval_required])
+
+ unless setting do
+ Pleroma.Config.put([:instance, :account_approval_required], true)
+ on_exit(fn -> Pleroma.Config.put([:instance, :account_approval_required], setting) end)
+ end
+
+ data = %{
+ :username => "lain",
+ :email => "lain@wired.jp",
+ :fullname => "lain iwakura",
+ :bio => "",
+ :password => "bear",
+ :confirm => "bear",
+ :reason => "I love anime"
+ }
+
+ {:ok, user} = TwitterAPI.register_user(data)
+ ObanHelpers.perform_all()
+
+ assert user.approval_pending
+
+ email = Pleroma.Emails.AdminEmail.new_unapproved_registration(admin, user)
+
+ notify_email = Pleroma.Config.get([:instance, :notify_email])
+ instance_name = Pleroma.Config.get([:instance, :name])
+
+ Swoosh.TestAssertions.assert_email_sent(
+ from: {instance_name, notify_email},
+ to: {admin.name, admin.email},
+ html_body: email.html_body
+ )
+ end
+
test "it registers a new user and parses mentions in the bio" do
data1 = %{
:username => "john",
:email => "john@gmail.com",
:fullname => "John Doe",
:bio => "test",
:password => "bear",
:confirm => "bear"
}
{:ok, user1} = TwitterAPI.register_user(data1)
data2 = %{
:username => "lain",
:email => "lain@wired.jp",
:fullname => "lain iwakura",
:bio => "@john test",
:password => "bear",
:confirm => "bear"
}
{:ok, user2} = TwitterAPI.register_user(data2)
expected_text =
~s(<span class="h-card"><a class="u-url mention" data-user="#{user1.id}" href="#{
user1.ap_id
}" rel="ugc">@<span>john</span></a></span> test)
assert user2.bio == expected_text
end
describe "register with one time token" do
setup do: clear_config([:instance, :registrations_open], false)
test "returns user on success" do
{:ok, invite} = UserInviteToken.create_invite()
data = %{
:username => "vinny",
:email => "pasta@pizza.vs",
:fullname => "Vinny Vinesauce",
:bio => "streamer",
:password => "hiptofbees",
:confirm => "hiptofbees",
:token => invite.token
}
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token)
assert invite.used == true
assert AccountView.render("show.json", %{user: user}) ==
AccountView.render("show.json", %{user: fetched_user})
end
test "returns error on invalid token" do
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",
:fullname => "Reaper Grim",
:bio => "Your time has come",
:password => "scythe",
:confirm => "scythe",
:token => "DudeLetMeInImAFairy"
}
{:error, msg} = TwitterAPI.register_user(data)
assert msg == "Invalid token"
refute User.get_cached_by_nickname("GrimReaper")
end
test "returns error on expired token" do
{:ok, invite} = UserInviteToken.create_invite()
UserInviteToken.update_invite!(invite, used: true)
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",
:fullname => "Reaper Grim",
:bio => "Your time has come",
:password => "scythe",
:confirm => "scythe",
:token => invite.token
}
{:error, msg} = TwitterAPI.register_user(data)
assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper")
end
end
describe "registers with date limited token" do
setup do: clear_config([:instance, :registrations_open], false)
setup do
data = %{
:username => "vinny",
:email => "pasta@pizza.vs",
:fullname => "Vinny Vinesauce",
:bio => "streamer",
:password => "hiptofbees",
:confirm => "hiptofbees"
}
check_fn = fn invite ->
data = Map.put(data, :token, invite.token)
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("vinny")
assert AccountView.render("show.json", %{user: user}) ==
AccountView.render("show.json", %{user: fetched_user})
end
{:ok, data: data, check_fn: check_fn}
end
test "returns user on success", %{check_fn: check_fn} do
{:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today()})
check_fn.(invite)
invite = Repo.get_by(UserInviteToken, token: invite.token)
refute invite.used
end
test "returns user on token which expired tomorrow", %{check_fn: check_fn} do
{:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), 1)})
check_fn.(invite)
invite = Repo.get_by(UserInviteToken, token: invite.token)
refute invite.used
end
test "returns an error on overdue date", %{data: data} do
{:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1)})
data = Map.put(data, "token", invite.token)
{:error, msg} = TwitterAPI.register_user(data)
assert msg == "Expired token"
refute User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token)
refute invite.used
end
end
describe "registers with reusable token" do
setup do: clear_config([:instance, :registrations_open], false)
test "returns user on success, after him registration fails" do
{:ok, invite} = UserInviteToken.create_invite(%{max_use: 100})
UserInviteToken.update_invite!(invite, uses: 99)
data = %{
:username => "vinny",
:email => "pasta@pizza.vs",
:fullname => "Vinny Vinesauce",
:bio => "streamer",
:password => "hiptofbees",
:confirm => "hiptofbees",
:token => invite.token
}
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token)
assert invite.used == true
assert AccountView.render("show.json", %{user: user}) ==
AccountView.render("show.json", %{user: fetched_user})
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",
:fullname => "Reaper Grim",
:bio => "Your time has come",
:password => "scythe",
:confirm => "scythe",
:token => invite.token
}
{:error, msg} = TwitterAPI.register_user(data)
assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper")
end
end
describe "registers with reusable date limited token" do
setup do: clear_config([:instance, :registrations_open], false)
test "returns user on success" do
{:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100})
data = %{
:username => "vinny",
:email => "pasta@pizza.vs",
:fullname => "Vinny Vinesauce",
:bio => "streamer",
:password => "hiptofbees",
:confirm => "hiptofbees",
:token => invite.token
}
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token)
refute invite.used
assert AccountView.render("show.json", %{user: user}) ==
AccountView.render("show.json", %{user: fetched_user})
end
test "error after max uses" do
{:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100})
UserInviteToken.update_invite!(invite, uses: 99)
data = %{
:username => "vinny",
:email => "pasta@pizza.vs",
:fullname => "Vinny Vinesauce",
:bio => "streamer",
:password => "hiptofbees",
:confirm => "hiptofbees",
:token => invite.token
}
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("vinny")
invite = Repo.get_by(UserInviteToken, token: invite.token)
assert invite.used == true
assert AccountView.render("show.json", %{user: user}) ==
AccountView.render("show.json", %{user: fetched_user})
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",
:fullname => "Reaper Grim",
:bio => "Your time has come",
:password => "scythe",
:confirm => "scythe",
:token => invite.token
}
{:error, msg} = TwitterAPI.register_user(data)
assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper")
end
test "returns error on overdue date" do
{:ok, invite} =
UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1), max_use: 100})
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",
:fullname => "Reaper Grim",
:bio => "Your time has come",
:password => "scythe",
:confirm => "scythe",
:token => invite.token
}
{:error, msg} = TwitterAPI.register_user(data)
assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper")
end
test "returns error on with overdue date and after max" do
{:ok, invite} =
UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1), max_use: 100})
UserInviteToken.update_invite!(invite, uses: 100)
data = %{
:username => "GrimReaper",
:email => "death@reapers.afterlife",
:fullname => "Reaper Grim",
:bio => "Your time has come",
:password => "scythe",
:confirm => "scythe",
:token => invite.token
}
{:error, msg} = TwitterAPI.register_user(data)
assert msg == "Expired token"
refute User.get_cached_by_nickname("GrimReaper")
end
end
test "it returns the error on registration problems" do
data = %{
:username => "lain",
:email => "lain@wired.jp",
:fullname => "lain iwakura",
:bio => "close the world."
}
{:error, error} = TwitterAPI.register_user(data)
assert is_binary(error)
refute User.get_cached_by_nickname("lain")
end
setup do
Supervisor.terminate_child(Pleroma.Supervisor, Cachex)
Supervisor.restart_child(Pleroma.Supervisor, Cachex)
:ok
end
end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 1, 5:18 AM (16 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1802523
Default Alt Text
(24 KB)

Event Timeline