This repository has been archived by the owner on Apr 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 472
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #325 from mssola/forgotten
Added the "Password forgotten" option
- Loading branch information
Showing
15 changed files
with
207 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# PasswordsController is a Devise controller that takes care of the "password | ||
# forgotten" mechanism. | ||
class PasswordsController < Devise::PasswordsController | ||
layout "authentication" | ||
|
||
# Re-implemented from Devise to respond with a proper message on error. | ||
def create | ||
self.resource = resource_class.send_reset_password_instructions(resource_params) | ||
yield resource if block_given? | ||
|
||
if successfully_sent?(resource) | ||
respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name)) | ||
else | ||
redirect_to new_user_password_path, alert: resource.errors.full_messages | ||
end | ||
end | ||
|
||
# Re-implemented from Devise to respond with a proper message on error. | ||
def update | ||
self.resource = resource_class.reset_password_by_token(resource_params) | ||
yield resource if block_given? | ||
|
||
if resource.errors.empty? | ||
update_success | ||
else | ||
token = params[:user][:reset_password_token] | ||
redirect_to "/users/password/edit?reset_password_token=#{token}", | ||
alert: resource.errors.full_messages | ||
end | ||
end | ||
|
||
protected | ||
|
||
def update_success | ||
resource.unlock_access! if unlockable?(resource) | ||
|
||
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active | ||
set_flash_message(:notice, flash_message) if is_flashing_format? | ||
sign_in(resource_name, resource) | ||
|
||
respond_with resource, location: after_resetting_password_path_for(resource) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class DeviseMailer < Devise::Mailer | ||
default from: "#{APP_CONFIG["email"]["name"]} <#{APP_CONFIG["email"]["from"]}>" | ||
default reply_to: APP_CONFIG["email"]["reply_to"] | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
section.row-0 | ||
.center-panel | ||
.col-md-4.col-sm-2.col-xs-1 | ||
.col-md-4.col-sm-8.col-xs-10.text-center | ||
= render 'shared/notifications' | ||
= image_tag 'layout/portus-logo-login-page.png', class: 'login-picture' | ||
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| | ||
= f.hidden_field :reset_password_token | ||
= f.password_field :password, class: 'input form-control input-lg', placeholder: 'Password', autofocus: true, autocomplete: "off", required: true | ||
= f.password_field :password_confirmation, class: 'input form-control input-lg', placeholder: 'Password confirmation', autocomplete: "off", required: true | ||
|
||
= f.button class: 'classbutton btn btn-primary btn-block btn-lg' do | ||
i.fa.fa-check Change my password | ||
|
||
.text-center = link_to 'Go back to the login page', new_user_session_url |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
section.row-0 | ||
.center-panel | ||
.col-md-4.col-sm-2.col-xs-1 | ||
.col-md-4.col-sm-8.col-xs-10.text-center | ||
= render 'shared/notifications' | ||
= image_tag 'layout/portus-logo-login-page.png', class: 'login-picture' | ||
= form_for(resource, as: resource_name, url: password_path(resource_name)) do |f| | ||
= f.email_field :email, class: 'input form-control input-lg', placeholder: 'Email', autofocus: true, required: true | ||
= f.button class: 'classbutton btn btn-primary btn-block btn-lg' do | ||
i.fa.fa-check Reset password | ||
|
||
.text-center = link_to 'Go back to the login page', new_user_session_url |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,17 @@ | |
# application. In order to change them, write your own config-local.yml file | ||
# (it will be ignored by git). | ||
|
||
# Settings for the Portus mailer. | ||
email: | ||
from: "[email protected]" | ||
name: "Portus" | ||
reply_to: "[email protected]" | ||
|
||
# If set to true, then SMTP will be used with the configuration values as | ||
# given in config/initializers/smtp.rb. Otherwise 'sendmail' will be used | ||
# (defaults to: /usr/sbin/sendmail -i -t). | ||
smtp: false | ||
|
||
# If enabled, then the profile picture will be picked from the Gravatar | ||
# associated with each user. See: https://en.gravatar.com/ | ||
gravatar: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,10 +10,10 @@ | |
# Configure the e-mail address which will be shown in Devise::Mailer, | ||
# note that it will be overwritten if you use your own mailer class | ||
# with default "from" parameter. | ||
config.mailer_sender = "[email protected]" | ||
# config.mailer_sender = "[email protected]" | ||
|
||
# Configure the class responsible to send e-mails. | ||
# config.mailer = 'Devise::Mailer' | ||
config.mailer = "DeviseMailer" | ||
|
||
# ==> ORM configuration | ||
# Load and configure the ORM. Supports :active_record (default) and | ||
|
@@ -185,7 +185,7 @@ | |
# ==> Configuration for :recoverable | ||
# | ||
# Defines which key will be used when recovering the password for an account | ||
# config.reset_password_keys = [:email] | ||
config.reset_password_keys = [:email] | ||
|
||
# Time interval you can reset your password with a reset password key. | ||
# Don't put a too small interval or your users won't have the time to | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Fetch the value of the given "PORTUS_SMTP_*" environment variable. If it's | ||
# not set, then it will raise an exception containing a descriptive message. | ||
def safe_env(name) | ||
name = "PORTUS_SMTP_#{name}".upcase | ||
unless ENV[name] | ||
raise StandardError, "SMTP is enabled but the environment variable '#{name}' has not been set!" | ||
end | ||
ENV[name] | ||
end | ||
|
||
if Rails.env.production? && APP_CONFIG["email"]["smtp"] | ||
ActionMailer::Base.smtp_settings = { | ||
address: safe_env("address"), | ||
port: safe_env("port"), | ||
user_name: safe_env("username"), | ||
password: safe_env("password"), | ||
domain: safe_env("domain"), | ||
authentication: :login, | ||
enable_starttls_auto: true | ||
} | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
require "rails_helper" | ||
|
||
describe PasswordsController do | ||
before :each do | ||
request.env["devise.mapping"] = Devise.mappings[:user] | ||
@user = create(:admin) | ||
@raw = @user.send_reset_password_instructions | ||
end | ||
|
||
it "updates the user's password on success" do | ||
put :update, "user" => { | ||
"reset_password_token" => @raw, | ||
"password" => "12341234", | ||
"password_confirmation" => "12341234" | ||
} | ||
|
||
expect(response.status).to eq 302 | ||
@user.reload | ||
expect(@user.valid_password?("12341234")).to be true | ||
end | ||
|
||
it "does nothing if the user's password does not match confirm" do | ||
put :update, "user" => { | ||
"reset_password_token" => @raw, | ||
"password" => "12341234", | ||
"password_confirmation" => "12341234asdasda" | ||
} | ||
|
||
expect(response.status).to eq 302 | ||
@user.reload | ||
expect(@user.valid_password?("12341234")).to be false | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
require "rails_helper" | ||
|
||
feature "Forgotten password support" do | ||
let!(:user) { create(:admin) } | ||
|
||
before :each do | ||
APP_CONFIG["email"] = { | ||
"from" => "[email protected]", | ||
"name" => "Portus", | ||
"reply_to" => "[email protected]" | ||
} | ||
end | ||
|
||
scenario "gives the user a link to reset their password", js: true do | ||
visit new_user_session_path | ||
expect(page).to_not have_content("Did you forget your password?") | ||
|
||
fill_in "Username", with: "random" | ||
fill_in "Password", with: "12341234" | ||
click_button "Login" | ||
|
||
expect(current_path).to eq new_user_session_path | ||
expect(page).to have_content("Did you forget your password?") | ||
click_link("Did you forget your password?") | ||
expect(current_path).to eq new_user_password_path | ||
end | ||
|
||
scenario "sends the reset email when appropiate", js: true do | ||
visit new_user_password_path | ||
|
||
fill_in "Email", with: "[email protected]" | ||
click_button "Reset password" | ||
expect(current_path).to eq new_user_password_path | ||
expect(page).to have_content("Email not found") | ||
|
||
fill_in "Email", with: user.email | ||
click_button "Reset password" | ||
expect(current_path).to eq new_user_session_path | ||
expect(page).to have_content("You will receive an email with instructions on " \ | ||
"how to reset your password in a few minutes.") | ||
|
||
# The email has been sent. | ||
mail = ActionMailer::Base.deliveries.first | ||
ActionMailer::Base.deliveries.clear | ||
expect(mail.to).to match_array [user.email] | ||
end | ||
end |