forked from External/greenlight
* <Added password reset system> * <Added rspec tests> * <Fixed code style> * <Added rescue for invalid smtp configuration>
This commit is contained in:
90
app/controllers/password_resets_controller.rb
Normal file
90
app/controllers/password_resets_controller.rb
Normal file
@ -0,0 +1,90 @@
|
||||
# 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 PasswordResetsController < ApplicationController
|
||||
before_action :disable_password_reset, unless: -> { Rails.configuration.enable_email_verification }
|
||||
before_action :find_user, only: [:edit, :update]
|
||||
before_action :valid_user, only: [:edit, :update]
|
||||
before_action :check_expiration, only: [:edit, :update]
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def create
|
||||
@user = User.find_by(email: params[:password_reset][:email].downcase)
|
||||
if @user
|
||||
@user.create_reset_digest
|
||||
@user.send_password_reset_email(request.base_url)
|
||||
redirect_to root_url, notice: I18n.t("email_sent")
|
||||
else
|
||||
redirect_to new_password_reset_path, notice: I18n.t("no_user_email_exists")
|
||||
end
|
||||
rescue => e
|
||||
logger.error "Error in email delivery: #{e}"
|
||||
redirect_to root_path, notice: I18n.t(params[:message], default: I18n.t("delivery_error"))
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if params[:user][:password].empty?
|
||||
flash.now[:notice] = I18n.t("password_empty_notice")
|
||||
render 'edit'
|
||||
elsif params[:user][:password] != params[:user][:password_confirmation]
|
||||
flash.now[:notice] = I18n.t("password_different_notice")
|
||||
render 'edit'
|
||||
elsif current_user.update_attributes(user_params)
|
||||
redirect_to root_path, notice: I18n.t("password_reset_success")
|
||||
else
|
||||
render 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_user
|
||||
@user = User.find_by(email: params[:email])
|
||||
end
|
||||
|
||||
def current_user
|
||||
@user
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:password, :password_confirmation)
|
||||
end
|
||||
|
||||
# Checks expiration of reset token.
|
||||
def check_expiration
|
||||
if current_user.password_reset_expired?
|
||||
redirect_to new_password_reset_url, notice: I18n.t("expired_reset_token")
|
||||
end
|
||||
end
|
||||
|
||||
# Confirms a valid user.
|
||||
def valid_user
|
||||
unless current_user&.email_verified && current_user.authenticated?(:reset, params[:id])
|
||||
redirect_to root_url
|
||||
end
|
||||
end
|
||||
|
||||
def disable_password_reset
|
||||
redirect_to '/404'
|
||||
end
|
||||
end
|
20
app/helpers/password_resets_helper.rb
Normal file
20
app/helpers/password_resets_helper.rb
Normal file
@ -0,0 +1,20 @@
|
||||
# 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/>.
|
||||
|
||||
module PasswordResetsHelper
|
||||
end
|
@ -24,4 +24,10 @@ class UserMailer < ApplicationMailer
|
||||
@url = url
|
||||
mail(to: @user.email, subject: t('landing.welcome'))
|
||||
end
|
||||
|
||||
def password_reset(user, url)
|
||||
@user = user
|
||||
@url = url
|
||||
mail to: user.email, subject: t('reset_password.subtitle')
|
||||
end
|
||||
end
|
||||
|
@ -17,6 +17,7 @@
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class User < ApplicationRecord
|
||||
attr_accessor :reset_token
|
||||
after_create :initialize_main_room
|
||||
before_save { email.try(:downcase!) }
|
||||
|
||||
@ -93,6 +94,30 @@ class User < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the password reset attributes.
|
||||
def create_reset_digest
|
||||
self.reset_token = User.new_token
|
||||
update_attribute(:reset_digest, User.digest(reset_token))
|
||||
update_attribute(:reset_sent_at, Time.zone.now)
|
||||
end
|
||||
|
||||
# Sends password reset email.
|
||||
def send_password_reset_email(url)
|
||||
UserMailer.password_reset(self, url).deliver_now
|
||||
end
|
||||
|
||||
# Returns true if the given token matches the digest.
|
||||
def authenticated?(attribute, token)
|
||||
digest = send("#{attribute}_digest")
|
||||
return false if digest.nil?
|
||||
BCrypt::Password.new(digest).is_password?(token)
|
||||
end
|
||||
|
||||
# Return true if password reset link expires
|
||||
def password_reset_expired?
|
||||
reset_sent_at < 2.hours.ago
|
||||
end
|
||||
|
||||
# Retrives a list of all a users rooms that are not the main room, sorted by last session date.
|
||||
def secondary_rooms
|
||||
secondary = (rooms - [main_room])
|
||||
@ -119,6 +144,16 @@ class User < ApplicationRecord
|
||||
provider == "greenlight"
|
||||
end
|
||||
|
||||
def self.digest(string)
|
||||
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
||||
BCrypt::Password.create(string, cost: cost)
|
||||
end
|
||||
|
||||
# Returns a random token.
|
||||
def self.new_token
|
||||
SecureRandom.urlsafe_base64
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Destory a users rooms when they are removed.
|
||||
|
50
app/views/password_resets/edit.html.erb
Normal file
50
app/views/password_resets/edit.html.erb
Normal file
@ -0,0 +1,50 @@
|
||||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<% unless flash.empty? %>
|
||||
<%= render "shared/error_banner" do %>
|
||||
<% flash.each do |key, value| %>
|
||||
<%= content_tag :div, value, class: "flash #{key} d-inline" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="container">
|
||||
<div class="row pt-7">
|
||||
<div class="col col-4 offset-4">
|
||||
<div class="card">
|
||||
<div class="card-header background">
|
||||
<h4 class="mt-2"><%= t("reset_password.subtitle") %></h4>
|
||||
</div>
|
||||
<div class="card-body background">
|
||||
<%= form_for(@user, url: password_reset_path(params[:id])) do |f| %>
|
||||
|
||||
<%= hidden_field_tag :email, @user.email %>
|
||||
|
||||
<%= f.label t('reset_password.password'), class: "form-label" %>
|
||||
<%= f.password_field :password, class: 'form-control' %>
|
||||
<br>
|
||||
|
||||
<%= f.label t('reset_password.confirm'), class: "form-label" %>
|
||||
<%= f.password_field :password_confirmation, class: 'form-control' %>
|
||||
<br>
|
||||
|
||||
<%= f.submit t('reset_password.update'), class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
43
app/views/password_resets/new.html.erb
Normal file
43
app/views/password_resets/new.html.erb
Normal file
@ -0,0 +1,43 @@
|
||||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<% unless flash.empty? %>
|
||||
<%= render "shared/error_banner" do %>
|
||||
<% flash.each do |key, value| %>
|
||||
<%= content_tag :div, value, class: "flash #{key} d-inline" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="container">
|
||||
<div class="row pt-7">
|
||||
<div class="col col-4 offset-4">
|
||||
<div class="card">
|
||||
<div class="card-header background">
|
||||
<h4 class="mt-2"><%= t("forgot_password.subtitle") %></h4>
|
||||
</div>
|
||||
<div class="card-body background">
|
||||
<%= form_for(:password_reset, url: password_resets_path) do |f| %>
|
||||
<%= f.label t("forgot_password.email"), class: "form-label" %>
|
||||
<%= f.email_field :email, class: "form-control" %>
|
||||
<br>
|
||||
|
||||
<%= f.submit t("forgot_password.submit"), class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -55,6 +55,13 @@
|
||||
<%= f.password_field :password, class: "form-control", placeholder: t("password"), value: "" %>
|
||||
</div>
|
||||
</div>
|
||||
<% if Rails.configuration.enable_email_verification %>
|
||||
<div class="form-group">
|
||||
<div class="input-icon">
|
||||
<%= link_to t("modal.login.forgot_password"), new_password_reset_path %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="form-footer">
|
||||
<%= f.submit t("login"), class: "btn btn-outline-primary btn-block btn-pill" %>
|
||||
</div>
|
||||
|
32
app/views/user_mailer/password_reset.html.erb
Normal file
32
app/views/user_mailer/password_reset.html.erb
Normal file
@ -0,0 +1,32 @@
|
||||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
<h1>Password reset</h1>
|
||||
|
||||
<p>Please click the link below to reset your password:</p>
|
||||
|
||||
<%= link_to "Reset password", edit_password_reset_url(@user.reset_token,
|
||||
email: @user.email,
|
||||
host: @url) %>
|
||||
|
||||
<p>This link will expire in two hours.</p>
|
||||
|
||||
<p>
|
||||
If you did not request your password to be reset, please ignore this email and
|
||||
your password will not be changed.
|
||||
</p>
|
26
app/views/user_mailer/password_reset.text.erb
Normal file
26
app/views/user_mailer/password_reset.text.erb
Normal file
@ -0,0 +1,26 @@
|
||||
<%
|
||||
# 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/>.
|
||||
%>
|
||||
|
||||
Please click the link below to reset your password:
|
||||
|
||||
<%= edit_password_reset_url(@user.reset_token, email: @user.email, host: @url) %>
|
||||
|
||||
This link will expire in two hours.
|
||||
|
||||
If you did not request your password to be reset, please ignore this email and
|
||||
your password will not be changed.
|
Reference in New Issue
Block a user