@@ -3,8 +3,6 @@ | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Captcha do | |||
import Pleroma.Web.Gettext | |||
alias Calendar.DateTime | |||
alias Plug.Crypto.KeyGenerator | |||
alias Plug.Crypto.MessageEncryptor | |||
@@ -37,19 +35,14 @@ defmodule Pleroma.Captcha do | |||
@doc false | |||
def handle_call(:new, _from, state) do | |||
enabled = Pleroma.Config.get([__MODULE__, :enabled]) | |||
if !enabled do | |||
if not enabled?() do | |||
{:reply, %{type: :none}, state} | |||
else | |||
new_captcha = method().new() | |||
secret_key_base = Pleroma.Config.get!([Pleroma.Web.Endpoint, :secret_key_base]) | |||
# This make salt a little different for two keys | |||
token = new_captcha[:token] | |||
secret = KeyGenerator.generate(secret_key_base, token <> "_encrypt") | |||
sign_secret = KeyGenerator.generate(secret_key_base, token <> "_sign") | |||
{secret, sign_secret} = secret_pair(new_captcha[:token]) | |||
# Basically copy what Phoenix.Token does here, add the time to | |||
# the actual data and make it a binary to then encrypt it | |||
encrypted_captcha_answer = | |||
@@ -71,44 +64,68 @@ defmodule Pleroma.Captcha do | |||
@doc false | |||
def handle_call({:validate, token, captcha, answer_data}, _from, state) do | |||
{:reply, do_validate(token, captcha, answer_data), state} | |||
end | |||
def enabled?, do: Pleroma.Config.get([__MODULE__, :enabled], false) | |||
defp seconds_valid, do: Pleroma.Config.get!([__MODULE__, :seconds_valid]) | |||
defp secret_pair(token) do | |||
secret_key_base = Pleroma.Config.get!([Pleroma.Web.Endpoint, :secret_key_base]) | |||
secret = KeyGenerator.generate(secret_key_base, token <> "_encrypt") | |||
sign_secret = KeyGenerator.generate(secret_key_base, token <> "_sign") | |||
{secret, sign_secret} | |||
end | |||
defp do_validate(token, captcha, answer_data) do | |||
with {:ok, %{at: at, answer_data: answer_md5}} <- validate_answer_data(token, answer_data), | |||
:ok <- validate_expiration(at), | |||
:ok <- validate_usage(token), | |||
:ok <- method().validate(token, captcha, answer_md5), | |||
{:ok, _} <- mark_captcha_as_used(token) do | |||
:ok | |||
end | |||
end | |||
defp validate_answer_data(token, answer_data) do | |||
{secret, sign_secret} = secret_pair(token) | |||
with false <- is_nil(answer_data), | |||
{:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret), | |||
%{at: at, answer_data: answer_md5} <- :erlang.binary_to_term(data) do | |||
{:ok, %{at: at, answer_data: answer_md5}} | |||
else | |||
_ -> {:error, :invalid_answer_data} | |||
end | |||
end | |||
defp validate_expiration(created_at) do | |||
# If the time found is less than (current_time-seconds_valid) then the time has already passed | |||
# Later we check that the time found is more than the presumed invalidatation time, that means | |||
# that the data is still valid and the captcha can be checked | |||
seconds_valid = Pleroma.Config.get!([Pleroma.Captcha, :seconds_valid]) | |||
valid_if_after = DateTime.subtract!(DateTime.now_utc(), seconds_valid) | |||
result = | |||
with false <- is_nil(answer_data), | |||
{:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret), | |||
%{at: at, answer_data: answer_md5} <- :erlang.binary_to_term(data) do | |||
try do | |||
if DateTime.before?(at, valid_if_after), | |||
do: throw({:error, dgettext("errors", "CAPTCHA expired")}) | |||
if not is_nil(Cachex.get!(:used_captcha_cache, token)), | |||
do: throw({:error, dgettext("errors", "CAPTCHA already used")}) | |||
res = method().validate(token, captcha, answer_md5) | |||
# Throw if an error occurs | |||
if res != :ok, do: throw(res) | |||
# Mark this captcha as used | |||
{:ok, _} = | |||
Cachex.put(:used_captcha_cache, token, true, ttl: :timer.seconds(seconds_valid)) | |||
:ok | |||
catch | |||
:throw, e -> e | |||
end | |||
else | |||
_ -> {:error, dgettext("errors", "Invalid answer data")} | |||
end | |||
{:reply, result, state} | |||
valid_if_after = DateTime.subtract!(DateTime.now_utc(), seconds_valid()) | |||
if DateTime.before?(created_at, valid_if_after) do | |||
{:error, :expired} | |||
else | |||
:ok | |||
end | |||
end | |||
defp validate_usage(token) do | |||
if is_nil(Cachex.get!(:used_captcha_cache, token)) do | |||
:ok | |||
else | |||
{:error, :already_used} | |||
end | |||
end | |||
defp mark_captcha_as_used(token) do | |||
ttl = seconds_valid() |> :timer.seconds() | |||
Cachex.put(:used_captcha_cache, token, true, ttl: ttl) | |||
end | |||
defp method, do: Pleroma.Config.get!([__MODULE__, :method]) | |||
@@ -3,7 +3,6 @@ | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Captcha.Kocaptcha do | |||
import Pleroma.Web.Gettext | |||
alias Pleroma.Captcha.Service | |||
@behaviour Service | |||
@@ -13,7 +12,7 @@ defmodule Pleroma.Captcha.Kocaptcha do | |||
case Tesla.get(endpoint <> "/new") do | |||
{:error, _} -> | |||
%{error: dgettext("errors", "Kocaptcha service unavailable")} | |||
%{error: :kocaptcha_service_unavailable} | |||
{:ok, res} -> | |||
json_resp = Jason.decode!(res.body) | |||
@@ -33,6 +32,6 @@ defmodule Pleroma.Captcha.Kocaptcha do | |||
if not is_nil(captcha) and | |||
:crypto.hash(:md5, captcha) |> Base.encode16() == String.upcase(answer_data), | |||
do: :ok, | |||
else: {:error, dgettext("errors", "Invalid CAPTCHA")} | |||
else: {:error, :invalid} | |||
end | |||
end |
@@ -3,7 +3,6 @@ | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Captcha.Native do | |||
import Pleroma.Web.Gettext | |||
alias Pleroma.Captcha.Service | |||
@behaviour Service | |||
@@ -11,7 +10,7 @@ defmodule Pleroma.Captcha.Native do | |||
def new do | |||
case Captcha.get() do | |||
:error -> | |||
%{error: dgettext("errors", "Captcha error")} | |||
%{error: :captcha_error} | |||
{:ok, answer_data, img_binary} -> | |||
%{ | |||
@@ -25,7 +24,7 @@ defmodule Pleroma.Captcha.Native do | |||
@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")} | |||
def validate(_token, _captcha, _answer), do: {:error, :invalid} | |||
defp token do | |||
10 | |||
@@ -94,24 +94,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||
@doc "POST /api/v1/accounts" | |||
def create(%{assigns: %{app: app}, body_params: params} = conn, _params) do | |||
params = | |||
params | |||
|> Map.take([ | |||
:email, | |||
:bio, | |||
:captcha_solution, | |||
:captcha_token, | |||
:captcha_answer_data, | |||
:token, | |||
:password, | |||
:fullname | |||
]) | |||
|> Map.put(:nickname, params.username) | |||
|> Map.put(:fullname, Map.get(params, :fullname, params.username)) | |||
|> Map.put(:confirm, params.password) | |||
|> Map.put(:trusted_app, app.trusted) | |||
with :ok <- validate_email_param(params), | |||
:ok <- TwitterAPI.validate_captcha(app, params), | |||
{:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true), | |||
{:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do | |||
json(conn, %{ | |||
@@ -121,7 +105,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||
created_at: Token.Utils.format_created_at(token) | |||
}) | |||
else | |||
{:error, errors} -> json_response(conn, :bad_request, errors) | |||
{:error, error} -> json_response(conn, :bad_request, %{error: error}) | |||
end | |||
end | |||
@@ -133,11 +117,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||
render_error(conn, :forbidden, "Invalid credentials") | |||
end | |||
defp validate_email_param(%{:email => email}) when not is_nil(email), do: :ok | |||
defp validate_email_param(%{email: email}) when not is_nil(email), do: :ok | |||
defp validate_email_param(_) do | |||
case Pleroma.Config.get([:instance, :account_activation_required]) do | |||
true -> {:error, %{"error" => "Missing parameters"}} | |||
true -> {:error, dgettext("errors", "Missing parameter: %{name}", name: "email")} | |||
_ -> :ok | |||
end | |||
end | |||
@@ -3,54 +3,27 @@ | |||
# 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 | |||
require Pleroma.Constants | |||
def register_user(params, opts \\ []) do | |||
params = | |||
params | |||
|> Map.take([ | |||
:nickname, | |||
:password, | |||
:captcha_solution, | |||
:captcha_token, | |||
:captcha_answer_data, | |||
:token, | |||
:email, | |||
:trusted_app | |||
]) | |||
|> Map.put(:bio, User.parse_bio(params[:bio] || "")) | |||
|> Map.put(:name, params.fullname) | |||
|> Map.put(:password_confirmation, params[:confirm]) | |||
case validate_captcha(params) do | |||
:ok -> | |||
if Pleroma.Config.get([:instance, :registrations_open]) do | |||
create_user(params, opts) | |||
else | |||
create_user_with_invite(params, opts) | |||
end | |||
|> 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]) | |||
{:error, error} -> | |||
# I have no idea how this error handling works | |||
{:error, %{error: Jason.encode!(%{captcha: [error]})}} | |||
end | |||
end | |||
defp validate_captcha(params) do | |||
if params[:trusted_app] || not Pleroma.Config.get([Pleroma.Captcha, :enabled]) do | |||
:ok | |||
if Pleroma.Config.get([:instance, :registrations_open]) do | |||
create_user(params, opts) | |||
else | |||
Pleroma.Captcha.validate( | |||
params[:captcha_token], | |||
params[:captcha_solution], | |||
params[:captcha_answer_data] | |||
) | |||
create_user_with_invite(params, opts) | |||
end | |||
end | |||
@@ -75,16 +48,17 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do | |||
{:error, changeset} -> | |||
errors = | |||
Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end) | |||
changeset | |||
|> Ecto.Changeset.traverse_errors(fn {msg, _opts} -> msg end) | |||
|> Jason.encode!() | |||
{:error, %{error: errors}} | |||
{:error, errors} | |||
end | |||
end | |||
def password_reset(nickname_or_email) do | |||
with true <- is_binary(nickname_or_email), | |||
%User{local: true, email: email} = user when not is_nil(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 | |||
@@ -106,4 +80,58 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do | |||
{: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 |
@@ -61,7 +61,7 @@ defmodule Pleroma.CaptchaTest do | |||
assert is_binary(answer) | |||
assert :ok = Native.validate(token, answer, answer) | |||
assert {:error, "Invalid CAPTCHA"} == Native.validate(token, answer, answer <> "foobar") | |||
assert {:error, :invalid} == Native.validate(token, answer, answer <> "foobar") | |||
end | |||
end | |||
@@ -78,6 +78,7 @@ defmodule Pleroma.CaptchaTest do | |||
assert is_binary(answer) | |||
assert :ok = Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", answer) | |||
Cachex.del(:used_captcha_cache, token) | |||
end | |||
test "doesn't validate invalid answer" do | |||
@@ -92,7 +93,7 @@ defmodule Pleroma.CaptchaTest do | |||
assert is_binary(answer) | |||
assert {:error, "Invalid answer data"} = | |||
assert {:error, :invalid_answer_data} = | |||
Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", answer <> "foobar") | |||
end | |||
@@ -108,7 +109,7 @@ defmodule Pleroma.CaptchaTest do | |||
assert is_binary(answer) | |||
assert {:error, "Invalid answer data"} = | |||
assert {:error, :invalid_answer_data} = | |||
Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", nil) | |||
end | |||
end | |||
@@ -6,12 +6,16 @@ defmodule Pleroma.Captcha.Mock do | |||
alias Pleroma.Captcha.Service | |||
@behaviour Service | |||
@solution "63615261b77f5354fb8c4e4986477555" | |||
def solution, do: @solution | |||
@impl Service | |||
def new, | |||
do: %{ | |||
type: :mock, | |||
token: "afa1815e14e29355e6c8f6b143a39fa2", | |||
answer_data: "63615261b77f5354fb8c4e4986477555", | |||
answer_data: @solution, | |||
url: "https://example.org/captcha.png" | |||
} | |||
@@ -925,7 +925,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do | |||
|> Map.put(:remote_ip, {127, 0, 0, 5}) | |||
|> post("/api/v1/accounts", Map.delete(valid_params, :email)) | |||
assert json_response_and_validate_schema(res, 400) == %{"error" => "Missing parameters"} | |||
assert json_response_and_validate_schema(res, 400) == | |||
%{"error" => "Missing parameter: email"} | |||
res = | |||
conn | |||
@@ -1093,6 +1094,91 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do | |||
end | |||
end | |||
describe "create account with enabled captcha" do | |||
setup %{conn: conn} do | |||
app_token = insert(:oauth_token, user: nil) | |||
conn = | |||
conn | |||
|> put_req_header("authorization", "Bearer " <> app_token.token) | |||
|> put_req_header("content-type", "multipart/form-data") | |||
[conn: conn] | |||
end | |||
setup do: clear_config([Pleroma.Captcha, :enabled], true) | |||
test "creates an account and returns 200 if captcha is valid", %{conn: conn} do | |||
%{token: token, answer_data: answer_data} = Pleroma.Captcha.new() | |||
params = %{ | |||
username: "lain", | |||
email: "lain@example.org", | |||
password: "PlzDontHackLain", | |||
agreement: true, | |||
captcha_solution: Pleroma.Captcha.Mock.solution(), | |||
captcha_token: token, | |||
captcha_answer_data: answer_data | |||
} | |||
assert %{ | |||
"access_token" => access_token, | |||
"created_at" => _, | |||
"scope" => ["read"], | |||
"token_type" => "Bearer" | |||
} = | |||
conn | |||
|> post("/api/v1/accounts", params) | |||
|> json_response_and_validate_schema(:ok) | |||
assert Token |> Repo.get_by(token: access_token) |> Repo.preload(:user) |> Map.get(:user) | |||
Cachex.del(:used_captcha_cache, token) | |||
end | |||
test "returns 400 if any captcha field is not provided", %{conn: conn} do | |||
captcha_fields = [:captcha_solution, :captcha_token, :captcha_answer_data] | |||
valid_params = %{ | |||
username: "lain", | |||
email: "lain@example.org", | |||
password: "PlzDontHackLain", | |||
agreement: true, | |||
captcha_solution: "xx", | |||
captcha_token: "xx", | |||
captcha_answer_data: "xx" | |||
} | |||
for field <- captcha_fields do | |||
expected = %{ | |||
"error" => "{\"captcha\":[\"Invalid CAPTCHA (Missing parameter: #{field})\"]}" | |||
} | |||
assert expected == | |||
conn | |||
|> post("/api/v1/accounts", Map.delete(valid_params, field)) | |||
|> json_response_and_validate_schema(:bad_request) | |||
end | |||
end | |||
test "returns an error if captcha is invalid", %{conn: conn} do | |||
params = %{ | |||
username: "lain", | |||
email: "lain@example.org", | |||
password: "PlzDontHackLain", | |||
agreement: true, | |||
captcha_solution: "cofe", | |||
captcha_token: "cofe", | |||
captcha_answer_data: "cofe" | |||
} | |||
assert %{"error" => "{\"captcha\":[\"Invalid answer data\"]}"} == | |||
conn | |||
|> post("/api/v1/accounts", params) | |||
|> json_response_and_validate_schema(:bad_request) | |||
end | |||
end | |||
describe "GET /api/v1/accounts/:id/lists - account_lists" do | |||
test "returns lists to which the account belongs" do | |||
%{user: user, conn: conn} = oauth_access(["read:lists"]) | |||
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
test "it registers a new user and returns the user." do | |||
data = %{ | |||
:nickname => "lain", | |||
:username => "lain", | |||
:email => "lain@wired.jp", | |||
:fullname => "lain iwakura", | |||
:password => "bear", | |||
@@ -35,7 +35,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
test "it registers a new user with empty string in bio and returns the user." do | |||
data = %{ | |||
:nickname => "lain", | |||
:username => "lain", | |||
:email => "lain@wired.jp", | |||
:fullname => "lain iwakura", | |||
:bio => "", | |||
@@ -60,7 +60,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
end | |||
data = %{ | |||
:nickname => "lain", | |||
:username => "lain", | |||
:email => "lain@wired.jp", | |||
:fullname => "lain iwakura", | |||
:bio => "", | |||
@@ -87,7 +87,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
test "it registers a new user and parses mentions in the bio" do | |||
data1 = %{ | |||
:nickname => "john", | |||
:username => "john", | |||
:email => "john@gmail.com", | |||
:fullname => "John Doe", | |||
:bio => "test", | |||
@@ -98,7 +98,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
{:ok, user1} = TwitterAPI.register_user(data1) | |||
data2 = %{ | |||
:nickname => "lain", | |||
:username => "lain", | |||
:email => "lain@wired.jp", | |||
:fullname => "lain iwakura", | |||
:bio => "@john test", | |||
@@ -123,7 +123,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
{:ok, invite} = UserInviteToken.create_invite() | |||
data = %{ | |||
:nickname => "vinny", | |||
:username => "vinny", | |||
:email => "pasta@pizza.vs", | |||
:fullname => "Vinny Vinesauce", | |||
:bio => "streamer", | |||
@@ -145,7 +145,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
test "returns error on invalid token" do | |||
data = %{ | |||
:nickname => "GrimReaper", | |||
:username => "GrimReaper", | |||
:email => "death@reapers.afterlife", | |||
:fullname => "Reaper Grim", | |||
:bio => "Your time has come", | |||
@@ -165,7 +165,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
UserInviteToken.update_invite!(invite, used: true) | |||
data = %{ | |||
:nickname => "GrimReaper", | |||
:username => "GrimReaper", | |||
:email => "death@reapers.afterlife", | |||
:fullname => "Reaper Grim", | |||
:bio => "Your time has come", | |||
@@ -186,7 +186,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
setup do | |||
data = %{ | |||
:nickname => "vinny", | |||
:username => "vinny", | |||
:email => "pasta@pizza.vs", | |||
:fullname => "Vinny Vinesauce", | |||
:bio => "streamer", | |||
@@ -250,7 +250,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
UserInviteToken.update_invite!(invite, uses: 99) | |||
data = %{ | |||
:nickname => "vinny", | |||
:username => "vinny", | |||
:email => "pasta@pizza.vs", | |||
:fullname => "Vinny Vinesauce", | |||
:bio => "streamer", | |||
@@ -269,7 +269,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
AccountView.render("show.json", %{user: fetched_user}) | |||
data = %{ | |||
:nickname => "GrimReaper", | |||
:username => "GrimReaper", | |||
:email => "death@reapers.afterlife", | |||
:fullname => "Reaper Grim", | |||
:bio => "Your time has come", | |||
@@ -292,7 +292,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
{:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100}) | |||
data = %{ | |||
:nickname => "vinny", | |||
:username => "vinny", | |||
:email => "pasta@pizza.vs", | |||
:fullname => "Vinny Vinesauce", | |||
:bio => "streamer", | |||
@@ -317,7 +317,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
UserInviteToken.update_invite!(invite, uses: 99) | |||
data = %{ | |||
:nickname => "vinny", | |||
:username => "vinny", | |||
:email => "pasta@pizza.vs", | |||
:fullname => "Vinny Vinesauce", | |||
:bio => "streamer", | |||
@@ -335,7 +335,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
AccountView.render("show.json", %{user: fetched_user}) | |||
data = %{ | |||
:nickname => "GrimReaper", | |||
:username => "GrimReaper", | |||
:email => "death@reapers.afterlife", | |||
:fullname => "Reaper Grim", | |||
:bio => "Your time has come", | |||
@@ -355,7 +355,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1), max_use: 100}) | |||
data = %{ | |||
:nickname => "GrimReaper", | |||
:username => "GrimReaper", | |||
:email => "death@reapers.afterlife", | |||
:fullname => "Reaper Grim", | |||
:bio => "Your time has come", | |||
@@ -377,7 +377,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
UserInviteToken.update_invite!(invite, uses: 100) | |||
data = %{ | |||
:nickname => "GrimReaper", | |||
:username => "GrimReaper", | |||
:email => "death@reapers.afterlife", | |||
:fullname => "Reaper Grim", | |||
:bio => "Your time has come", | |||
@@ -395,16 +395,15 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do | |||
test "it returns the error on registration problems" do | |||
data = %{ | |||
:nickname => "lain", | |||
:username => "lain", | |||
:email => "lain@wired.jp", | |||
:fullname => "lain iwakura", | |||
:bio => "close the world.", | |||
:password => "bear" | |||
:bio => "close the world." | |||
} | |||
{:error, error_object} = TwitterAPI.register_user(data) | |||
{:error, error} = TwitterAPI.register_user(data) | |||
assert is_binary(error_object[:error]) | |||
assert is_binary(error) | |||
refute User.get_cached_by_nickname("lain") | |||
end | |||