Resourceful routing for passwords
This also matches the routes used by devise
This commit is contained in:
parent
1d0f588d62
commit
4bca24a7be
7 changed files with 60 additions and 35 deletions
|
@ -19,7 +19,7 @@ class Ability
|
||||||
can [:confirm, :confirm_resend, :confirm_email], :confirmation
|
can [:confirm, :confirm_resend, :confirm_email], :confirmation
|
||||||
can [:index, :rss, :show, :comments], DiaryEntry
|
can [:index, :rss, :show, :comments], DiaryEntry
|
||||||
can [:index], Note
|
can [:index], Note
|
||||||
can [:lost_password, :reset_password], :password
|
can [:new, :create, :edit, :update], :password
|
||||||
can [:index, :show], Redaction
|
can [:index, :show], Redaction
|
||||||
can [:new, :create, :destroy], :session
|
can [:new, :create, :destroy], :session
|
||||||
can [:index, :show, :data, :georss, :picture, :icon], Trace
|
can [:index, :show, :data, :georss, :picture, :icon], Trace
|
||||||
|
|
|
@ -9,34 +9,50 @@ class PasswordsController < ApplicationController
|
||||||
|
|
||||||
authorize_resource :class => false
|
authorize_resource :class => false
|
||||||
|
|
||||||
before_action :check_database_writable, :only => [:lost_password, :reset_password]
|
before_action :check_database_writable
|
||||||
|
|
||||||
def lost_password
|
def new
|
||||||
|
@title = t ".title"
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
@title = t ".title"
|
@title = t ".title"
|
||||||
|
|
||||||
if request.post?
|
if params[:token]
|
||||||
user = User.visible.find_by(:email => params[:email])
|
token = UserToken.find_by(:token => params[:token])
|
||||||
|
|
||||||
if user.nil?
|
if token
|
||||||
users = User.visible.where("LOWER(email) = LOWER(?)", params[:email])
|
self.current_user = token.user
|
||||||
|
|
||||||
user = users.first if users.count == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if user
|
|
||||||
token = user.tokens.create
|
|
||||||
UserMailer.lost_password(user, token).deliver_later
|
|
||||||
flash[:notice] = t ".notice email on way"
|
|
||||||
redirect_to login_path
|
|
||||||
else
|
else
|
||||||
flash.now[:error] = t ".notice email cannot find"
|
flash[:error] = t ".flash token bad"
|
||||||
|
redirect_to :action => "new"
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
head :bad_request
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_password
|
def create
|
||||||
@title = t ".title"
|
user = User.visible.find_by(:email => params[:email])
|
||||||
|
|
||||||
|
if user.nil?
|
||||||
|
users = User.visible.where("LOWER(email) = LOWER(?)", params[:email])
|
||||||
|
|
||||||
|
user = users.first if users.count == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if user
|
||||||
|
token = user.tokens.create
|
||||||
|
UserMailer.lost_password(user, token).deliver_later
|
||||||
|
flash[:notice] = t ".notice email on way"
|
||||||
|
redirect_to login_path
|
||||||
|
else
|
||||||
|
flash.now[:error] = t ".notice email cannot find"
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
if params[:token]
|
if params[:token]
|
||||||
token = UserToken.find_by(:token => params[:token])
|
token = UserToken.find_by(:token => params[:token])
|
||||||
|
|
||||||
|
@ -54,11 +70,13 @@ class PasswordsController < ApplicationController
|
||||||
session[:fingerprint] = current_user.fingerprint
|
session[:fingerprint] = current_user.fingerprint
|
||||||
flash[:notice] = t ".flash changed"
|
flash[:notice] = t ".flash changed"
|
||||||
successful_login(current_user)
|
successful_login(current_user)
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
flash[:error] = t ".flash token bad"
|
flash[:error] = t ".flash token bad"
|
||||||
redirect_to :action => "lost_password"
|
redirect_to :action => "new"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
head :bad_request
|
head :bad_request
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<h1><%= t ".heading", :user => current_user.display_name %></h1>
|
<h1><%= t ".heading", :user => current_user.display_name %></h1>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= bootstrap_form_for current_user, :url => { :action => "reset_password" }, :html => { :method => :post } do |f| %>
|
<%= bootstrap_form_for current_user, :url => { :action => "update" }, :html => { :method => :post } do |f| %>
|
||||||
<%= f.hidden_field :token, :name => "token", :value => params[:token] %>
|
<%= f.hidden_field :token, :name => "token", :value => params[:token] %>
|
||||||
<%= f.password_field :pass_crypt, :value => "" %>
|
<%= f.password_field :pass_crypt, :value => "" %>
|
||||||
<%= f.password_field :pass_crypt_confirmation, :value => "" %>
|
<%= f.password_field :pass_crypt_confirmation, :value => "" %>
|
|
@ -1732,18 +1732,21 @@ en:
|
||||||
destroy:
|
destroy:
|
||||||
destroyed: "Message deleted"
|
destroyed: "Message deleted"
|
||||||
passwords:
|
passwords:
|
||||||
lost_password:
|
new:
|
||||||
title: "Lost password"
|
title: "Lost password"
|
||||||
heading: "Forgotten Password?"
|
heading: "Forgotten Password?"
|
||||||
email address: "Email Address:"
|
email address: "Email Address:"
|
||||||
new password button: "Reset password"
|
new password button: "Reset password"
|
||||||
help_text: "Enter the email address you used to sign up, we will send a link to it that you can use to reset your password."
|
help_text: "Enter the email address you used to sign up, we will send a link to it that you can use to reset your password."
|
||||||
|
create:
|
||||||
notice email on way: "Sorry you lost it :-( but an email is on its way so you can reset it soon."
|
notice email on way: "Sorry you lost it :-( but an email is on its way so you can reset it soon."
|
||||||
notice email cannot find: "Could not find that email address, sorry."
|
notice email cannot find: "Could not find that email address, sorry."
|
||||||
reset_password:
|
edit:
|
||||||
title: "Reset password"
|
title: "Reset password"
|
||||||
heading: "Reset Password for %{user}"
|
heading: "Reset Password for %{user}"
|
||||||
reset: "Reset Password"
|
reset: "Reset Password"
|
||||||
|
flash token bad: "Did not find that token, check the URL maybe?"
|
||||||
|
update:
|
||||||
flash changed: "Your password has been changed."
|
flash changed: "Your password has been changed."
|
||||||
flash token bad: "Did not find that token, check the URL maybe?"
|
flash token bad: "Did not find that token, check the URL maybe?"
|
||||||
preferences:
|
preferences:
|
||||||
|
|
|
@ -172,8 +172,12 @@ OpenStreetMap::Application.routes.draw do
|
||||||
match "/user/confirm" => "confirmations#confirm", :via => [:get, :post]
|
match "/user/confirm" => "confirmations#confirm", :via => [:get, :post]
|
||||||
match "/user/confirm-email" => "confirmations#confirm_email", :via => [:get, :post]
|
match "/user/confirm-email" => "confirmations#confirm_email", :via => [:get, :post]
|
||||||
post "/user/go_public" => "users#go_public"
|
post "/user/go_public" => "users#go_public"
|
||||||
match "/user/reset-password" => "passwords#reset_password", :via => [:get, :post], :as => :user_reset_password
|
scope :user, :as => "user" do
|
||||||
match "/user/forgot-password" => "passwords#lost_password", :via => [:get, :post], :as => :user_forgot_password
|
get "forgot-password" => "passwords#new"
|
||||||
|
post "forgot-password" => "passwords#create"
|
||||||
|
get "reset-password" => "passwords#edit"
|
||||||
|
post "reset-password" => "passwords#update"
|
||||||
|
end
|
||||||
get "/user/suspended" => "users#suspended"
|
get "/user/suspended" => "users#suspended"
|
||||||
|
|
||||||
get "/index.html", :to => redirect(:path => "/")
|
get "/index.html", :to => redirect(:path => "/")
|
||||||
|
|
|
@ -6,19 +6,19 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
||||||
def test_routes
|
def test_routes
|
||||||
assert_routing(
|
assert_routing(
|
||||||
{ :path => "/user/forgot-password", :method => :get },
|
{ :path => "/user/forgot-password", :method => :get },
|
||||||
{ :controller => "passwords", :action => "lost_password" }
|
{ :controller => "passwords", :action => "new" }
|
||||||
)
|
)
|
||||||
assert_routing(
|
assert_routing(
|
||||||
{ :path => "/user/forgot-password", :method => :post },
|
{ :path => "/user/forgot-password", :method => :post },
|
||||||
{ :controller => "passwords", :action => "lost_password" }
|
{ :controller => "passwords", :action => "create" }
|
||||||
)
|
)
|
||||||
assert_routing(
|
assert_routing(
|
||||||
{ :path => "/user/reset-password", :method => :get },
|
{ :path => "/user/reset-password", :method => :get },
|
||||||
{ :controller => "passwords", :action => "reset_password" }
|
{ :controller => "passwords", :action => "edit" }
|
||||||
)
|
)
|
||||||
assert_routing(
|
assert_routing(
|
||||||
{ :path => "/user/reset-password", :method => :post },
|
{ :path => "/user/reset-password", :method => :post },
|
||||||
{ :controller => "passwords", :action => "reset_password" }
|
{ :controller => "passwords", :action => "update" }
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
||||||
# Test fetching the lost password page
|
# Test fetching the lost password page
|
||||||
get user_forgot_password_path
|
get user_forgot_password_path
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template :lost_password
|
assert_template :new
|
||||||
assert_select "div#notice", false
|
assert_select "div#notice", false
|
||||||
|
|
||||||
# Test resetting using the address as recorded for a user that has an
|
# Test resetting using the address as recorded for a user that has an
|
||||||
|
@ -41,7 +41,7 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template :lost_password
|
assert_template :new
|
||||||
|
|
||||||
# Resetting with POST should work
|
# Resetting with POST should work
|
||||||
assert_difference "ActionMailer::Base.deliveries.size", 1 do
|
assert_difference "ActionMailer::Base.deliveries.size", 1 do
|
||||||
|
@ -80,7 +80,7 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template :lost_password
|
assert_template :new
|
||||||
assert_select ".alert.alert-danger", /^Could not find that email address/
|
assert_select ".alert.alert-danger", /^Could not find that email address/
|
||||||
|
|
||||||
# Test resetting using the address as recorded for a user that has an
|
# Test resetting using the address as recorded for a user that has an
|
||||||
|
@ -124,7 +124,7 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
||||||
# Test a request with a bogus token
|
# Test a request with a bogus token
|
||||||
get user_reset_password_path, :params => { :token => "made_up_token" }
|
get user_reset_password_path, :params => { :token => "made_up_token" }
|
||||||
assert_response :redirect
|
assert_response :redirect
|
||||||
assert_redirected_to :action => :lost_password
|
assert_redirected_to :action => :new
|
||||||
|
|
||||||
# Create a valid token for a user
|
# Create a valid token for a user
|
||||||
token = user.tokens.create
|
token = user.tokens.create
|
||||||
|
@ -132,12 +132,12 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest
|
||||||
# Test a request with a valid token
|
# Test a request with a valid token
|
||||||
get user_reset_password_path, :params => { :token => token.token }
|
get user_reset_password_path, :params => { :token => token.token }
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template :reset_password
|
assert_template :edit
|
||||||
|
|
||||||
# Test that errors are reported for erroneous submissions
|
# Test that errors are reported for erroneous submissions
|
||||||
post user_reset_password_path, :params => { :token => token.token, :user => { :pass_crypt => "new_password", :pass_crypt_confirmation => "different_password" } }
|
post user_reset_password_path, :params => { :token => token.token, :user => { :pass_crypt => "new_password", :pass_crypt_confirmation => "different_password" } }
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_template :reset_password
|
assert_template :edit
|
||||||
assert_select "div.invalid-feedback"
|
assert_select "div.invalid-feedback"
|
||||||
|
|
||||||
# Test setting a new password
|
# Test setting a new password
|
||||||
|
|
Loading…
Add table
Reference in a new issue