GRN-56: Correctly implemented the account verification flow (#367)

* Correctly implemented the account verification flow

* Fixed issues with redirect locations
This commit is contained in:
farhatahmad
2019-02-22 16:47:02 -05:00
committed by Jesus Federico
parent 5521402ee7
commit c60e25f71c
17 changed files with 337 additions and 141 deletions

View File

@ -0,0 +1,76 @@
# frozen_string_literal: true
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
#
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
class AccountActivationsController < ApplicationController
before_action :ensure_unauthenticated
before_action :find_user
# GET /account_activations
def show
render :verify
end
# GET /account_activations/edit
def edit
if @user && !@user.email_verified? && @user.authenticated?(:activation, params[:token])
@user.activate
flash[:success] = I18n.t("verify.activated") + " " + I18n.t("verify.signin")
else
flash[:alert] = I18n.t("verify.invalid")
end
redirect_to root_url
end
# GET /account_activations/resend
def resend
if @user.email_verified
flash[:alert] = I18n.t("verify.already_verified")
else
begin
@user.send_activation_email(verification_link)
rescue => e
logger.error "Error in email delivery: #{e}"
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent")
end
end
redirect_to(root_path)
end
private
def verification_link
request.base_url + edit_account_activation_path(token: @user.activation_token, email: @user.email)
end
def ensure_unauthenticated
redirect_to current_user.main_room if current_user
end
def email_params
params.require(:email).permit(:token)
end
def find_user
@user = User.find_by!(email: params[:email], provider: "greenlight")
end
end

View File

@ -18,9 +18,11 @@
class RoomsController < ApplicationController
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
before_action :validate_verified_email, unless: -> { !Rails.configuration.enable_email_verification }
before_action :validate_verified_email, except: [:show, :join],
unless: -> { !Rails.configuration.enable_email_verification }
before_action :find_room, except: :create
before_action :verify_room_ownership, except: [:create, :show, :join, :logout]
before_action :verify_room_owner_verified, only: [:show, :join]
include RecordingsHelper
META_LISTED = "gl-listed"
@ -240,7 +242,19 @@ class RoomsController < ApplicationController
def validate_verified_email
if current_user
redirect_to resend_path unless current_user.email_verified
redirect_to account_activation_path(current_user) unless current_user.email_verified
end
end
def verify_room_owner_verified
unless @room.owner.email_verified
flash[:alert] = t("room.unavailable")
if current_user
redirect_to current_user.main_room
else
redirect_to root_path
end
end
end
end

View File

@ -31,7 +31,11 @@ class SessionsController < ApplicationController
if user && !user.greenlight_account?
redirect_to root_path, alert: I18n.t("invalid_login_method")
elsif user.try(:authenticate, session_params[:password])
login(user)
if user.email_verified
login(user)
else
redirect_to(account_activation_path(email: user.email)) && return
end
else
redirect_to root_path, alert: I18n.t("invalid_credentials")
end

View File

@ -30,19 +30,37 @@ class UsersController < ApplicationController
@user = User.new(user_params)
@user.provider = "greenlight"
if Rails.configuration.enable_email_verification && @user.save
# Check if user already exists
if User.exists?(email: user_params[:email], provider: @user.provider)
existing_user = User.find_by!(email: user_params[:email], provider: @user.provider)
if Rails.configuration.enable_email_verification && !existing_user.email_verified?
# User exists but is not verified
redirect_to(account_activation_path(email: existing_user.email)) && return
else
# User already exists and is verified
# Attempt to save so that the correct errors appear
@user.save
render(:new) && return
end
elsif Rails.configuration.enable_email_verification && @user.save
begin
UserMailer.verify_email(@user, verification_link(@user)).deliver
login(@user)
@user.send_activation_email(verification_link)
rescue => e
logger.error "Error in email delivery: #{e}"
mailer_delivery_fail
flash[:alert] = I18n.t(params[:message], default: I18n.t("delivery_error"))
else
flash[:success] = I18n.t("email_sent")
end
redirect_to(root_path) && return
elsif @user.save
# User doesn't exist and email verification is turned off
@user.activate
login(@user)
else
# Handle error on user creation.
render :new
render(:new) && return
end
end
@ -145,53 +163,16 @@ class UsersController < ApplicationController
end
end
# GET | POST /u/verify/confirm
def confirm
if !current_user || current_user.uid != params[:user_uid]
redirect_to '/404'
elsif current_user.email_verified
login(current_user)
elsif params[:email_verified] == "true"
current_user.update_attributes(email_verified: true)
login(current_user)
else
render 'verify'
end
end
# GET /u/verify/resend
def resend
if !current_user
redirect_to '/404'
elsif current_user.email_verified
login(current_user)
elsif params[:email_verified] == "false"
begin
UserMailer.verify_email(current_user, verification_link(current_user)).deliver
render 'verify'
rescue => e
logger.error "Error in email delivery: #{e}"
mailer_delivery_fail
end
else
render 'verify'
end
end
private
def mailer_delivery_fail
redirect_to root_path, alert: I18n.t(params[:message], default: I18n.t("delivery_error"))
end
def verification_link(user)
request.base_url + confirm_path(user.uid)
end
def find_user
@user = User.find_by!(uid: params[:user_uid])
end
def verification_link
request.base_url + edit_account_activation_path(token: @user.activation_token, email: @user.email)
end
def ensure_unauthenticated
redirect_to current_user.main_room if current_user
end