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:
parent
e3389c84d1
commit
8fe66d81f1
|
@ -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
|
|
@ -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
|
@url = url
|
||||||
mail(to: @user.email, subject: t('landing.welcome'))
|
mail(to: @user.email, subject: t('landing.welcome'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def password_reset(user, url)
|
||||||
|
@user = user
|
||||||
|
@url = url
|
||||||
|
mail to: user.email, subject: t('reset_password.subtitle')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
|
attr_accessor :reset_token
|
||||||
after_create :initialize_main_room
|
after_create :initialize_main_room
|
||||||
before_save { email.try(:downcase!) }
|
before_save { email.try(:downcase!) }
|
||||||
|
|
||||||
|
@ -93,6 +94,30 @@ class User < ApplicationRecord
|
||||||
end
|
end
|
||||||
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.
|
# Retrives a list of all a users rooms that are not the main room, sorted by last session date.
|
||||||
def secondary_rooms
|
def secondary_rooms
|
||||||
secondary = (rooms - [main_room])
|
secondary = (rooms - [main_room])
|
||||||
|
@ -119,6 +144,16 @@ class User < ApplicationRecord
|
||||||
provider == "greenlight"
|
provider == "greenlight"
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
# Destory a users rooms when they are removed.
|
# Destory a users rooms when they are removed.
|
||||||
|
|
|
@ -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>
|
|
@ -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: "" %>
|
<%= f.password_field :password, class: "form-control", placeholder: t("password"), value: "" %>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="form-footer">
|
||||||
<%= f.submit t("login"), class: "btn btn-outline-primary btn-block btn-pill" %>
|
<%= f.submit t("login"), class: "btn btn-outline-primary btn-block btn-pill" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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>
|
|
@ -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.
|
|
@ -29,6 +29,7 @@ en:
|
||||||
delivery_error: An error occured during email delivery. Please contact an administrator!
|
delivery_error: An error occured during email delivery. Please contact an administrator!
|
||||||
docs: Documentation
|
docs: Documentation
|
||||||
email: Email
|
email: Email
|
||||||
|
email_sent: Email Sent!
|
||||||
enter_your_name: Enter your name!
|
enter_your_name: Enter your name!
|
||||||
errors:
|
errors:
|
||||||
internal:
|
internal:
|
||||||
|
@ -49,6 +50,7 @@ en:
|
||||||
unprocessable:
|
unprocessable:
|
||||||
message: Oops! Request is unprocessable.
|
message: Oops! Request is unprocessable.
|
||||||
help: Unforunately this isn't a valid request.
|
help: Unforunately this isn't a valid request.
|
||||||
|
expired_reset_token: Password reset link has expired!
|
||||||
features:
|
features:
|
||||||
title: Features
|
title: Features
|
||||||
rooms: Personalized Rooms
|
rooms: Personalized Rooms
|
||||||
|
@ -57,6 +59,10 @@ en:
|
||||||
authentication: User Authentication
|
authentication: User Authentication
|
||||||
footer:
|
footer:
|
||||||
powered_by: Powered by %{href}.
|
powered_by: Powered by %{href}.
|
||||||
|
forgot_password:
|
||||||
|
subtitle: Forgot Password
|
||||||
|
email: Email
|
||||||
|
submit: Submit
|
||||||
go_back: Go back
|
go_back: Go back
|
||||||
greenlight: Greenlight
|
greenlight: Greenlight
|
||||||
header:
|
header:
|
||||||
|
@ -109,13 +115,18 @@ en:
|
||||||
login:
|
login:
|
||||||
or: or
|
or: or
|
||||||
with: Sign in with %{provider}
|
with: Sign in with %{provider}
|
||||||
|
forgot_password: Forgot Password?
|
||||||
rename_recording:
|
rename_recording:
|
||||||
|
|
||||||
rename_room:
|
rename_room:
|
||||||
name_placeholder: Enter a new room name...
|
name_placeholder: Enter a new room name...
|
||||||
name_update_success: Room name successfully changed!
|
name_update_success: Room name successfully changed!
|
||||||
|
no_user_email_exists: There is no existing user with the email specified. Please make sure you typed it correctly.
|
||||||
omniauth_error: An error occured while authenticating with omniauth. Please try again or contact an administrator!
|
omniauth_error: An error occured while authenticating with omniauth. Please try again or contact an administrator!
|
||||||
password: Password
|
password: Password
|
||||||
|
password_empty_notice: Password cannot be empty.
|
||||||
|
password_reset_success: Password has been reset.
|
||||||
|
password_different_notice: Password Confirmation does not match.
|
||||||
provider:
|
provider:
|
||||||
google: Google
|
google: Google
|
||||||
microsoft_office365: Office 365
|
microsoft_office365: Office 365
|
||||||
|
@ -136,6 +147,11 @@ en:
|
||||||
public: Public
|
public: Public
|
||||||
unlisted: Unlisted
|
unlisted: Unlisted
|
||||||
rename: Rename
|
rename: Rename
|
||||||
|
reset_password:
|
||||||
|
subtitle: Reset Password
|
||||||
|
password: New Password
|
||||||
|
confirm: New Password Confirmation
|
||||||
|
update: Update Password
|
||||||
room:
|
room:
|
||||||
invited: You have been invited to join
|
invited: You have been invited to join
|
||||||
invite_participants: Invite Participants
|
invite_participants: Invite Participants
|
||||||
|
|
|
@ -31,6 +31,9 @@ Rails.application.routes.draw do
|
||||||
# Redirect to terms page
|
# Redirect to terms page
|
||||||
match '/terms', to: 'users#terms', via: [:get, :post]
|
match '/terms', to: 'users#terms', via: [:get, :post]
|
||||||
|
|
||||||
|
# Password reset resources.
|
||||||
|
resources :password_resets, only: [:new, :create, :edit, :update]
|
||||||
|
|
||||||
# User resources.
|
# User resources.
|
||||||
scope '/u' do
|
scope '/u' do
|
||||||
# Verification Routes
|
# Verification Routes
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# 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 AddResetToUsers < ActiveRecord::Migration[5.0]
|
||||||
|
def change
|
||||||
|
add_column :users, :reset_digest, :string
|
||||||
|
add_column :users, :reset_sent_at, :datetime
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20181113174230) do
|
ActiveRecord::Schema.define(version: 20181217142710) do
|
||||||
|
|
||||||
create_table "rooms", force: :cascade do |t|
|
create_table "rooms", force: :cascade do |t|
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
|
@ -40,10 +40,13 @@ ActiveRecord::Schema.define(version: 20181113174230) do
|
||||||
t.string "image"
|
t.string "image"
|
||||||
t.string "password_digest"
|
t.string "password_digest"
|
||||||
t.boolean "accepted_terms", default: false
|
t.boolean "accepted_terms", default: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.boolean "email_verified", default: false
|
t.boolean "email_verified", default: false
|
||||||
t.string "language", default: "default"
|
t.string "language", default: "default"
|
||||||
|
t.string "role", default: "moderator"
|
||||||
|
t.string "reset_digest"
|
||||||
|
t.datetime "reset_sent_at"
|
||||||
t.index ["password_digest"], name: "index_users_on_password_digest", unique: true
|
t.index ["password_digest"], name: "index_users_on_password_digest", unique: true
|
||||||
t.index ["room_id"], name: "index_users_on_room_id"
|
t.index ["room_id"], name: "index_users_on_room_id"
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
# 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/>.
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
def random_valid_user_params
|
||||||
|
pass = Faker::Internet.password(8)
|
||||||
|
{
|
||||||
|
user: {
|
||||||
|
name: Faker::Name.first_name,
|
||||||
|
email: Faker::Internet.email,
|
||||||
|
password: pass,
|
||||||
|
password_confirmation: pass,
|
||||||
|
accepted_terms: true,
|
||||||
|
email_verified: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe PasswordResetsController, type: :controller do
|
||||||
|
describe "POST #create" do
|
||||||
|
context "allow mail notifications" do
|
||||||
|
before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) }
|
||||||
|
|
||||||
|
it "redirects to root url if email is sent" do
|
||||||
|
user = create(:user)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
password_reset: {
|
||||||
|
email: user.email,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
post :create, params: params
|
||||||
|
expect(response).to redirect_to(root_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reloads the page if no email exists in the database" do
|
||||||
|
params = {
|
||||||
|
password_reset: {
|
||||||
|
email: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
post :create, params: params
|
||||||
|
expect(response).to redirect_to(new_password_reset_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "does not allow mail notifications" do
|
||||||
|
before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(false) }
|
||||||
|
|
||||||
|
it "renders a 404 page upon if email notifications are disabled" do
|
||||||
|
get :create
|
||||||
|
expect(response).to redirect_to("/404")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH #update" do
|
||||||
|
before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) }
|
||||||
|
|
||||||
|
context "valid user" do
|
||||||
|
it "reloads page with notice if password is empty" do
|
||||||
|
token = "reset_token"
|
||||||
|
|
||||||
|
controller.stub(:valid_user).and_return(nil)
|
||||||
|
controller.stub(:check_expiration).and_return(nil)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
id: token,
|
||||||
|
user: {
|
||||||
|
password: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
patch :update, params: params
|
||||||
|
expect(response).to render_template(:edit)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reloads page with notice if password is confirmation doesn't match" do
|
||||||
|
token = "reset_token"
|
||||||
|
|
||||||
|
controller.stub(:valid_user).and_return(nil)
|
||||||
|
controller.stub(:check_expiration).and_return(nil)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
id: token,
|
||||||
|
user: {
|
||||||
|
password: :password,
|
||||||
|
password_confirmation: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
patch :update, params: params
|
||||||
|
expect(response).to render_template(:edit)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates attributes if the password update is a success" do
|
||||||
|
user = create(:user)
|
||||||
|
token = "reset_token"
|
||||||
|
|
||||||
|
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
||||||
|
user.reset_digest = BCrypt::Password.create(token, cost: cost)
|
||||||
|
|
||||||
|
controller.stub(:valid_user).and_return(nil)
|
||||||
|
controller.stub(:check_expiration).and_return(nil)
|
||||||
|
controller.stub(:current_user).and_return(user)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
id: token,
|
||||||
|
user: {
|
||||||
|
password: :password,
|
||||||
|
password_confirmation: :password,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
patch :update, params: params
|
||||||
|
expect(response).to redirect_to(root_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -109,4 +109,21 @@ describe User, type: :model do
|
||||||
expect(user.name_chunk).to eq("exa")
|
expect(user.name_chunk).to eq("exa")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'password reset' do
|
||||||
|
it 'creates token and respective reset digest' do
|
||||||
|
user = create(:user)
|
||||||
|
|
||||||
|
reset_digest_success = user.create_reset_digest
|
||||||
|
expect(reset_digest_success).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'verifies if password reset link expired' do
|
||||||
|
user = create(:user)
|
||||||
|
user.create_reset_digest
|
||||||
|
|
||||||
|
expired = user.password_reset_expired?
|
||||||
|
expect(expired).to be_in([true, false])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue