Merge branch '114_email_confirmation' into 'develop'

[#114] Email confirmation

See merge request pleroma/pleroma!546
This commit is contained in:
kaniini 2018-12-20 13:28:36 +00:00
commit 2e2030ada8
21 changed files with 398 additions and 24 deletions

View file

@ -1,6 +1,6 @@
defmodule Pleroma.Web.AdminAPI.AdminAPIController do
use Pleroma.Web, :controller
alias Pleroma.{User, Repo}
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Relay
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
@ -26,7 +26,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
conn,
%{"nickname" => nickname, "email" => email, "password" => password}
) do
new_user = %{
user_data = %{
nickname: nickname,
name: nickname,
email: email,
@ -35,11 +35,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
bio: "."
}
User.register_changeset(%User{}, new_user)
|> Repo.insert!()
changeset = User.register_changeset(%User{}, user_data, confirmed: true)
{:ok, user} = User.register(changeset)
conn
|> json(new_user.nickname)
|> json(user.nickname)
end
def tag_users(conn, %{"nicknames" => nicknames, "tags" => tags}) do

View file

@ -110,7 +110,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def user(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do
with %User{} = user <- Repo.get(User, id) do
with %User{} = user <- Repo.get(User, id),
true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do
account = AccountView.render("account.json", %{user: user, for: for_user})
json(conn, account)
else

View file

@ -62,6 +62,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
# Pleroma extension
pleroma: %{
confirmation_pending: user_info.confirmation_pending,
tags: user.tags
}
}

View file

@ -132,6 +132,7 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
banner: Keyword.get(instance, :banner_upload_limit),
background: Keyword.get(instance, :background_upload_limit)
},
accountActivationRequired: Keyword.get(instance, :account_activation_required, false),
invitesEnabled: Keyword.get(instance, :invites_enabled, false),
features: features
}

View file

@ -31,6 +31,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
}) do
with %User{} = user <- User.get_by_nickname_or_email(name),
true <- Pbkdf2.checkpw(password, user.password_hash),
{:auth_active, true} <- {:auth_active, User.auth_active?(user)},
%App{} = app <- Repo.get_by(App, client_id: client_id),
{:ok, auth} <- Authorization.create_authorization(app, user) do
# Special case: Local MastodonFE.
@ -63,6 +64,15 @@ defmodule Pleroma.Web.OAuth.OAuthController do
redirect(conn, external: url)
end
else
{:auth_active, false} ->
conn
|> put_flash(:error, "Account confirmation pending")
|> put_status(:forbidden)
|> authorize(params)
error ->
error
end
end
@ -101,6 +111,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
with %App{} = app <- get_app_from_request(conn, params),
%User{} = user <- User.get_by_nickname_or_email(name),
true <- Pbkdf2.checkpw(password, user.password_hash),
{:auth_active, true} <- {:auth_active, User.auth_active?(user)},
{:ok, auth} <- Authorization.create_authorization(app, user),
{:ok, token} <- Token.exchange_token(app, auth) do
response = %{
@ -113,6 +124,11 @@ defmodule Pleroma.Web.OAuth.OAuthController do
json(conn, response)
else
{:auth_active, false} ->
conn
|> put_status(:forbidden)
|> json(%{error: "Account confirmation pending"})
_error ->
put_status(conn, 400)
|> json(%{error: "Invalid credentials"})

View file

@ -283,6 +283,15 @@ defmodule Pleroma.Web.Router do
post("/account/register", TwitterAPI.Controller, :register)
post("/account/password_reset", TwitterAPI.Controller, :password_reset)
get(
"/account/confirm_email/:user_id/:token",
TwitterAPI.Controller,
:confirm_email,
as: :confirm_email
)
post("/account/resend_confirmation_email", TwitterAPI.Controller, :resend_confirmation_email)
get("/search", TwitterAPI.Controller, :search)
get("/statusnet/tags/timeline/:tag", TwitterAPI.Controller, :public_and_external_timeline)
end

View file

@ -174,6 +174,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
closed: if(Keyword.get(instance, :registrations_open), do: "0", else: "1"),
private: if(Keyword.get(instance, :public, true), do: "0", else: "1"),
vapidPublicKey: vapid_public_key,
accountActivationRequired:
if(Keyword.get(instance, :account_activation_required, false), do: "1", else: "0"),
invitesEnabled: if(Keyword.get(instance, :invites_enabled, false), do: "1", else: "0")
}

View file

@ -1,8 +1,10 @@
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
alias Pleroma.{UserInviteToken, User, Activity, Repo, Object}
alias Pleroma.{UserEmail, Mailer}
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.TwitterAPI.UserView
alias Pleroma.Web.CommonAPI
import Ecto.Query
def create_status(%User{} = user, %{"status" => _} = data) do
@ -161,10 +163,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
cond do
registrations_open || (!is_nil(token) && !token.used) ->
changeset = User.register_changeset(%User{info: %{}}, params)
changeset = User.register_changeset(%User{}, params)
with {:ok, user} <- Repo.insert(changeset) do
with {:ok, user} <- User.register(changeset) do
!registrations_open && UserInviteToken.mark_as_used(token.token)
{:ok, user}
else
{:error, changeset} ->
@ -189,8 +192,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
%User{local: true} = user <- User.get_by_nickname_or_email(nickname_or_email),
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
user
|> Pleroma.UserEmail.password_reset_email(token_record.token)
|> Pleroma.Mailer.deliver()
|> UserEmail.password_reset_email(token_record.token)
|> Mailer.deliver()
else
false ->
{:error, "bad user identifier"}

View file

@ -96,10 +96,15 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
end
def show_user(conn, params) do
with {:ok, shown} <- TwitterAPI.get_user(params) do
for_user = conn.assigns.user
with {:ok, shown} <- TwitterAPI.get_user(params),
true <-
User.auth_active?(shown) ||
(for_user && (for_user.id == shown.id || User.superuser?(for_user))) do
params =
if user = conn.assigns.user do
%{user: shown, for: user}
if for_user do
%{user: shown, for: for_user}
else
%{user: shown}
end
@ -110,6 +115,11 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
else
{:error, msg} ->
bad_request_reply(conn, msg)
false ->
conn
|> put_status(404)
|> json(%{error: "Unconfirmed user"})
end
end
@ -372,6 +382,29 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
end
end
def confirm_email(conn, %{"user_id" => uid, "token" => token}) do
with %User{} = user <- Repo.get(User, uid),
true <- user.local,
true <- user.info.confirmation_pending,
true <- user.info.confirmation_token == token,
info_change <- User.Info.confirmation_changeset(user.info, :confirmed),
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_change),
{:ok, _} <- User.update_and_set_cache(changeset) do
conn
|> redirect(to: "/")
end
end
def resend_confirmation_email(conn, params) do
nickname_or_email = params["email"] || params["nickname"]
with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
{:ok, _} <- User.try_send_confirmation_email(user) do
conn
|> json_response(:no_content, "")
end
end
def update_avatar(%{assigns: %{user: user}} = conn, params) do
{:ok, object} = ActivityPub.upload(params, type: :avatar)
change = Changeset.change(user, %{avatar: object.data})

View file

@ -81,6 +81,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
# Pleroma extension
"pleroma" => %{
"confirmation_pending" => user_info.confirmation_pending,
"tags" => user.tags
}
}