From: Andy Allan Date: Wed, 7 Apr 2021 15:04:59 +0000 (+0100) Subject: Move confirmation methods into ConfirmationsController X-Git-Tag: live~1703^2 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/094d6c8bb9949825e1e66b07ba39190a8b57aa0b Move confirmation methods into ConfirmationsController --- diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb index 5db1b7eb5..9c832b43a 100644 --- a/app/abilities/ability.rb +++ b/app/abilities/ability.rb @@ -16,13 +16,14 @@ class Ability if Settings.status != "database_offline" can [:index, :feed], Changeset can :index, ChangesetComment + can [:confirm, :confirm_resend, :confirm_email], :confirmation can [:index, :rss, :show, :comments], DiaryEntry can [:index], Note can [:lost_password, :reset_password], :password can [:index, :show], Redaction can [:new, :create, :destroy], :session can [:index, :show, :data, :georss, :picture, :icon], Trace - can [:terms, :new, :create, :save, :confirm, :confirm_resend, :confirm_email, :show, :auth_success, :auth_failure], User + can [:terms, :new, :create, :save, :show, :auth_success, :auth_failure], User can [:index, :show, :blocks_on, :blocks_by], UserBlock can [:index, :show], Node can [:index, :show, :full, :ways_for_node], Way diff --git a/app/controllers/concerns/session_methods.rb b/app/controllers/concerns/session_methods.rb index 089a82ed4..dd6458b1b 100644 --- a/app/controllers/concerns/session_methods.rb +++ b/app/controllers/concerns/session_methods.rb @@ -81,7 +81,7 @@ module SessionMethods def unconfirmed_login(user) session[:token] = user.tokens.create.token - redirect_to :controller => "users", :action => "confirm", :display_name => user.display_name + redirect_to :controller => "confirmations", :action => "confirm", :display_name => user.display_name session.delete(:remember_me) session.delete(:referer) diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb new file mode 100644 index 000000000..b77ed09b3 --- /dev/null +++ b/app/controllers/confirmations_controller.rb @@ -0,0 +1,137 @@ +class ConfirmationsController < ApplicationController + include SessionMethods + + layout "site" + + before_action :authorize_web + before_action :set_locale + before_action :check_database_readable + + authorize_resource :class => false + + before_action :check_database_writable, :only => [:confirm, :confirm_email] + before_action :require_cookies, :only => [:confirm] + + def confirm + if request.post? + token = UserToken.find_by(:token => params[:confirm_string]) + if token&.user&.active? + flash[:error] = t("confirmations.confirm.already active") + redirect_to login_path + elsif !token || token.expired? + flash[:error] = t("confirmations.confirm.unknown token") + redirect_to :action => "confirm" + elsif !token.user.visible? + render_unknown_user token.user.display_name + else + user = token.user + user.status = "active" + user.email_valid = true + flash[:notice] = gravatar_status_message(user) if gravatar_enable(user) + user.save! + referer = safe_referer(token.referer) if token.referer + token.destroy + + if session[:token] + token = UserToken.find_by(:token => session[:token]) + session.delete(:token) + else + token = nil + end + + if token.nil? || token.user != user + flash[:notice] = t("confirmations.confirm.success") + redirect_to login_path(:referer => referer) + else + token.destroy + + session[:user] = user.id + session[:fingerprint] = user.fingerprint + + redirect_to referer || welcome_path + end + end + else + user = User.visible.find_by(:display_name => params[:display_name]) + + redirect_to root_path if user.nil? || user.active? + end + end + + def confirm_resend + user = User.visible.find_by(:display_name => params[:display_name]) + token = UserToken.find_by(:token => session[:token]) + + if user.nil? || token.nil? || token.user != user + flash[:error] = t "confirmations.confirm_resend.failure", :name => params[:display_name] + else + UserMailer.signup_confirm(user, user.tokens.create).deliver_later + flash[:notice] = t "confirmations.confirm_resend.success_html", :email => user.email, :sender => Settings.support_email + end + + redirect_to login_path + end + + def confirm_email + if request.post? + token = UserToken.find_by(:token => params[:confirm_string]) + if token&.user&.new_email? + self.current_user = token.user + current_user.email = current_user.new_email + current_user.new_email = nil + current_user.email_valid = true + gravatar_enabled = gravatar_enable(current_user) + if current_user.save + flash[:notice] = if gravatar_enabled + "#{t('confirmations.confirm_email.success')} #{gravatar_status_message(current_user)}" + else + t("confirmations.confirm_email.success") + end + else + flash[:errors] = current_user.errors + end + current_user.tokens.delete_all + session[:user] = current_user.id + session[:fingerprint] = current_user.fingerprint + redirect_to :controller => :users, :action => :account, :display_name => current_user.display_name + elsif token + flash[:error] = t "confirmations.confirm_email.failure" + redirect_to :controller => :users, :action => :account, :display_name => token.user.display_name + else + flash[:error] = t "confirmations.confirm_email.unknown_token" + end + end + end + + private + + ## + # check if this user has a gravatar and set the user pref is true + def gravatar_enable(user) + # code from example https://en.gravatar.com/site/implement/images/ruby/ + return false if user.avatar.attached? + + begin + hash = Digest::MD5.hexdigest(user.email.downcase) + url = "https://www.gravatar.com/avatar/#{hash}?d=404" # without d=404 we will always get an image back + response = OSM.http_client.get(URI.parse(url)) + available = response.success? + rescue StandardError + available = false + end + + oldsetting = user.image_use_gravatar + user.image_use_gravatar = available + oldsetting != user.image_use_gravatar + end + + ## + # display a message about th current status of the gravatar setting + def gravatar_status_message(user) + if user.image_use_gravatar + t "users.account.gravatar.enabled" + else + t "users.account.gravatar.disabled" + end + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 7c732d46e..43933041c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -12,8 +12,8 @@ class UsersController < ApplicationController authorize_resource before_action :require_self, :only => [:account] - before_action :check_database_writable, :only => [:new, :account, :confirm, :confirm_email, :go_public] - before_action :require_cookies, :only => [:new, :confirm] + before_action :check_database_writable, :only => [:new, :account, :go_public] + before_action :require_cookies, :only => [:new] before_action :lookup_user_by_name, :only => [:set_status, :destroy] before_action :allow_thirdparty_images, :only => [:show, :account] @@ -109,7 +109,7 @@ class UsersController < ApplicationController else session[:token] = current_user.tokens.create.token UserMailer.signup_confirm(current_user, current_user.tokens.create(:referer => referer)).deliver_later - redirect_to :action => "confirm", :display_name => current_user.display_name + redirect_to :controller => :confirmations, :action => :confirm, :display_name => current_user.display_name end else render :action => "new", :referer => params[:referer] @@ -217,97 +217,6 @@ class UsersController < ApplicationController end end - def confirm - if request.post? - token = UserToken.find_by(:token => params[:confirm_string]) - if token&.user&.active? - flash[:error] = t("users.confirm.already active") - redirect_to login_path - elsif !token || token.expired? - flash[:error] = t("users.confirm.unknown token") - redirect_to :action => "confirm" - elsif !token.user.visible? - render_unknown_user token.user.display_name - else - user = token.user - user.status = "active" - user.email_valid = true - flash[:notice] = gravatar_status_message(user) if gravatar_enable(user) - user.save! - referer = safe_referer(token.referer) if token.referer - token.destroy - - if session[:token] - token = UserToken.find_by(:token => session[:token]) - session.delete(:token) - else - token = nil - end - - if token.nil? || token.user != user - flash[:notice] = t("users.confirm.success") - redirect_to login_path(:referer => referer) - else - token.destroy - - session[:user] = user.id - session[:fingerprint] = user.fingerprint - - redirect_to referer || welcome_path - end - end - else - user = User.visible.find_by(:display_name => params[:display_name]) - - redirect_to root_path if user.nil? || user.active? - end - end - - def confirm_resend - user = User.visible.find_by(:display_name => params[:display_name]) - token = UserToken.find_by(:token => session[:token]) - - if user.nil? || token.nil? || token.user != user - flash[:error] = t "users.confirm_resend.failure", :name => params[:display_name] - else - UserMailer.signup_confirm(user, user.tokens.create).deliver_later - flash[:notice] = t "users.confirm_resend.success_html", :email => user.email, :sender => Settings.support_email - end - - redirect_to login_path - end - - def confirm_email - if request.post? - token = UserToken.find_by(:token => params[:confirm_string]) - if token&.user&.new_email? - self.current_user = token.user - current_user.email = current_user.new_email - current_user.new_email = nil - current_user.email_valid = true - gravatar_enabled = gravatar_enable(current_user) - if current_user.save - flash[:notice] = if gravatar_enabled - "#{t('users.confirm_email.success')} #{gravatar_status_message(current_user)}" - else - t("users.confirm_email.success") - end - else - flash[:errors] = current_user.errors - end - current_user.tokens.delete_all - session[:user] = current_user.id - session[:fingerprint] = current_user.fingerprint - redirect_to :action => "account", :display_name => current_user.display_name - elsif token - flash[:error] = t "users.confirm_email.failure" - redirect_to :action => "account", :display_name => token.user.display_name - else - flash[:error] = t "users.confirm_email.unknown_token" - end - end - end - def show @user = User.find_by(:display_name => params[:display_name]) @@ -568,34 +477,4 @@ class UsersController < ApplicationController dns.getresources(domain, Resolv::DNS::Resource::IN::MX).collect(&:exchange).collect(&:to_s) end end - - ## - # check if this user has a gravatar and set the user pref is true - def gravatar_enable(user) - # code from example https://en.gravatar.com/site/implement/images/ruby/ - return false if user.avatar.attached? - - begin - hash = Digest::MD5.hexdigest(user.email.downcase) - url = "https://www.gravatar.com/avatar/#{hash}?d=404" # without d=404 we will always get an image back - response = OSM.http_client.get(URI.parse(url)) - available = response.success? - rescue StandardError - available = false - end - - oldsetting = user.image_use_gravatar - user.image_use_gravatar = available - oldsetting != user.image_use_gravatar - end - - ## - # display a message about th current status of the gravatar setting - def gravatar_status_message(user) - if user.image_use_gravatar - t "users.account.gravatar.enabled" - else - t "users.account.gravatar.disabled" - end - end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index bb43bc962..0664b8475 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -12,7 +12,7 @@ class UserMailer < ApplicationMailer def signup_confirm(user, token) with_recipient_locale user do - @url = url_for(:controller => "users", :action => "confirm", + @url = url_for(:controller => "confirmations", :action => "confirm", :display_name => user.display_name, :confirm_string => token.token) @@ -24,7 +24,7 @@ class UserMailer < ApplicationMailer def email_confirm(user, token) with_recipient_locale user do @address = user.new_email - @url = url_for(:controller => "users", :action => "confirm_email", + @url = url_for(:controller => "confirmations", :action => "confirm_email", :confirm_string => token.token) mail :to => user.new_email, diff --git a/app/views/users/confirm.html.erb b/app/views/confirmations/confirm.html.erb similarity index 100% rename from app/views/users/confirm.html.erb rename to app/views/confirmations/confirm.html.erb diff --git a/app/views/users/confirm_email.html.erb b/app/views/confirmations/confirm_email.html.erb similarity index 100% rename from app/views/users/confirm_email.html.erb rename to app/views/confirmations/confirm_email.html.erb diff --git a/config/locales/en.yml b/config/locales/en.yml index 38f977263..4cfdf5754 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1519,6 +1519,29 @@ en: details_html: "More details about the changeset can be found at %{url}." unsubscribe: 'To unsubscribe from updates to this changeset, visit %{url} and click "Unsubscribe".' unsubscribe_html: 'To unsubscribe from updates to this changeset, visit %{url} and click "Unsubscribe".' + confirmations: + confirm: + heading: Check your email! + introduction_1: | + We sent you a confirmation email. + introduction_2: | + Confirm your account by clicking on the link in the email and you'll be able to start mapping. + press confirm button: "Press the confirm button below to activate your account." + button: Confirm + success: "Confirmed your account, thanks for signing up!" + already active: "This account has already been confirmed." + unknown token: "That confirmation code has expired or does not exist." + reconfirm_html: "If you need us to resend the confirmation email, click here." + confirm_resend: + success_html: "We've sent a new confirmation note to %{email} and as soon as you confirm your account you'll be able to get mapping.

If you use an antispam system which sends confirmation requests then please make sure you whitelist %{sender} as we are unable to reply to any confirmation requests." + failure: "User %{name} not found." + confirm_email: + heading: Confirm a change of email address + press confirm button: "Press the confirm button below to confirm your new email address." + button: Confirm + success: "Confirmed your change of email address!" + failure: "An email address has already been confirmed with this token." + unknown_token: "That confirmation code has expired or does not exist." messages: inbox: title: "Inbox" @@ -2451,28 +2474,6 @@ en: return to profile: Return to profile flash update success confirm needed: "User information updated successfully. Check your email for a note to confirm your new email address." flash update success: "User information updated successfully." - confirm: - heading: Check your email! - introduction_1: | - We sent you a confirmation email. - introduction_2: | - Confirm your account by clicking on the link in the email and you'll be able to start mapping. - press confirm button: "Press the confirm button below to activate your account." - button: Confirm - success: "Confirmed your account, thanks for signing up!" - already active: "This account has already been confirmed." - unknown token: "That confirmation code has expired or does not exist." - reconfirm_html: "If you need us to resend the confirmation email, click here." - confirm_resend: - success_html: "We've sent a new confirmation note to %{email} and as soon as you confirm your account you'll be able to get mapping.

If you use an antispam system which sends confirmation requests then please make sure you whitelist %{sender} as we are unable to reply to any confirmation requests." - failure: "User %{name} not found." - confirm_email: - heading: Confirm a change of email address - press confirm button: "Press the confirm button below to confirm your new email address." - button: Confirm - success: "Confirmed your change of email address!" - failure: "An email address has already been confirmed with this token." - unknown_token: "That confirmation code has expired or does not exist." set_home: flash success: "Home location saved successfully" go_public: diff --git a/config/routes.rb b/config/routes.rb index 52e5a69e1..da3921e4a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -156,10 +156,10 @@ OpenStreetMap::Application.routes.draw do post "/user/new" => "users#create" get "/user/terms" => "users#terms" post "/user/save" => "users#save" - get "/user/:display_name/confirm/resend" => "users#confirm_resend", :as => :user_confirm_resend - match "/user/:display_name/confirm" => "users#confirm", :via => [:get, :post] - match "/user/confirm" => "users#confirm", :via => [:get, :post] - match "/user/confirm-email" => "users#confirm_email", :via => [:get, :post] + get "/user/:display_name/confirm/resend" => "confirmations#confirm_resend", :as => :user_confirm_resend + match "/user/:display_name/confirm" => "confirmations#confirm", :via => [:get, :post] + match "/user/confirm" => "confirmations#confirm", :via => [:get, :post] + match "/user/confirm-email" => "confirmations#confirm_email", :via => [:get, :post] post "/user/go_public" => "users#go_public" match "/user/reset-password" => "passwords#reset_password", :via => [:get, :post], :as => :user_reset_password match "/user/forgot-password" => "passwords#lost_password", :via => [:get, :post], :as => :user_forgot_password diff --git a/test/controllers/confirmations_controller_test.rb b/test/controllers/confirmations_controller_test.rb new file mode 100644 index 000000000..bae0158cd --- /dev/null +++ b/test/controllers/confirmations_controller_test.rb @@ -0,0 +1,339 @@ +require "test_helper" + +class UsersControllerTest < ActionDispatch::IntegrationTest + ## + # test all routes which lead to this controller + def test_routes + assert_routing( + { :path => "/user/username/confirm", :method => :get }, + { :controller => "confirmations", :action => "confirm", :display_name => "username" } + ) + assert_routing( + { :path => "/user/username/confirm", :method => :post }, + { :controller => "confirmations", :action => "confirm", :display_name => "username" } + ) + assert_routing( + { :path => "/user/username/confirm/resend", :method => :get }, + { :controller => "confirmations", :action => "confirm_resend", :display_name => "username" } + ) + + assert_routing( + { :path => "/user/confirm", :method => :get }, + { :controller => "confirmations", :action => "confirm" } + ) + assert_routing( + { :path => "/user/confirm", :method => :post }, + { :controller => "confirmations", :action => "confirm" } + ) + assert_routing( + { :path => "/user/confirm-email", :method => :get }, + { :controller => "confirmations", :action => "confirm_email" } + ) + assert_routing( + { :path => "/user/confirm-email", :method => :post }, + { :controller => "confirmations", :action => "confirm_email" } + ) + end + + def test_confirm_get + user = build(:user, :pending) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create.token + + get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_response :success + assert_template :confirm + end + + def test_confirm_get_already_confirmed + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create.token + + # Get the confirmation page + get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_response :success + assert_template :confirm + + # Confirm the user + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to welcome_path + + # Now try to get the confirmation page again + get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_response :redirect + assert_redirected_to root_path + end + + def test_confirm_success_no_token_no_referer + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create.token + + post logout_path + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to login_path + assert_match(/Confirmed your account/, flash[:notice]) + end + + def test_confirm_success_good_token_no_referer + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create.token + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to welcome_path + end + + def test_confirm_success_bad_token_no_referer + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create.token + + post logout_path + session_for(create(:user)) + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to login_path + assert_match(/Confirmed your account/, flash[:notice]) + end + + def test_confirm_success_no_token_with_referer + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token + + post logout_path + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to login_path(:referer => new_diary_entry_path) + assert_match(/Confirmed your account/, flash[:notice]) + end + + def test_confirm_success_good_token_with_referer + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to new_diary_entry_path + end + + def test_confirm_success_bad_token_with_referer + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token + + post logout_path + session_for(create(:user)) + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to login_path(:referer => new_diary_entry_path) + assert_match(/Confirmed your account/, flash[:notice]) + end + + def test_confirm_expired_token + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create(:expiry => 1.day.ago).token + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to :action => "confirm" + assert_match(/confirmation code has expired/, flash[:error]) + end + + def test_confirm_already_confirmed + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token + + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to new_diary_entry_path + + post logout_path + + confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_redirected_to login_path + assert_match(/already been confirmed/, flash[:error]) + end + + def test_confirm_deleted + user = build(:user, :pending) + stub_gravatar_request(user.email) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + confirm_string = User.find_by(:email => user.email).tokens.create.token + + User.find_by(:display_name => user.display_name).update(:status => "deleted") + + # Get the confirmation page + get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_response :redirect + assert_redirected_to root_path + + # Confirm the user + post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } + assert_response :not_found + assert_template :no_such_user + end + + def test_confirm_resend_success + user = build(:user, :pending) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + + assert_difference "ActionMailer::Base.deliveries.size", 1 do + perform_enqueued_jobs do + get user_confirm_resend_path(user) + end + end + + assert_response :redirect + assert_redirected_to login_path + assert_match(/sent a new confirmation/, flash[:notice]) + + email = ActionMailer::Base.deliveries.last + + assert_equal user.email, email.to.first + + ActionMailer::Base.deliveries.clear + end + + def test_confirm_resend_no_token + user = build(:user, :pending) + # only complete first half of registration + post user_new_path, :params => { :user => user.attributes } + + assert_no_difference "ActionMailer::Base.deliveries.size" do + perform_enqueued_jobs do + get user_confirm_resend_path(user) + end + end + + assert_response :redirect + assert_redirected_to login_path + assert_match "User #{user.display_name} not found.", flash[:error] + end + + def test_confirm_resend_deleted + user = build(:user, :pending) + post user_new_path, :params => { :user => user.attributes } + post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } + + User.find_by(:display_name => user.display_name).update(:status => "deleted") + + assert_no_difference "ActionMailer::Base.deliveries.size" do + perform_enqueued_jobs do + get user_confirm_resend_path(user) + end + end + + assert_response :redirect + assert_redirected_to login_path + assert_match "User #{user.display_name} not found.", flash[:error] + end + + def test_confirm_resend_unknown_user + assert_no_difference "ActionMailer::Base.deliveries.size" do + perform_enqueued_jobs do + get user_confirm_resend_path(:display_name => "No Such User") + end + end + + assert_response :redirect + assert_redirected_to login_path + assert_match "User No Such User not found.", flash[:error] + end + + def test_confirm_email_get + user = create(:user) + confirm_string = user.tokens.create.token + + get user_confirm_email_path, :params => { :confirm_string => confirm_string } + assert_response :success + assert_template :confirm_email + end + + def test_confirm_email_success + user = create(:user, :new_email => "test-new@example.com") + stub_gravatar_request(user.new_email) + confirm_string = user.tokens.create.token + + post user_confirm_email_path, :params => { :confirm_string => confirm_string } + assert_response :redirect + assert_redirected_to :controller => :users, :action => :account, :display_name => user.display_name + assert_match(/Confirmed your change of email address/, flash[:notice]) + end + + def test_confirm_email_already_confirmed + user = create(:user) + confirm_string = user.tokens.create.token + + post user_confirm_email_path, :params => { :confirm_string => confirm_string } + assert_response :redirect + assert_redirected_to :controller => :users, :action => :account, :display_name => user.display_name + assert_match(/already been confirmed/, flash[:error]) + end + + def test_confirm_email_bad_token + post user_confirm_email_path, :params => { :confirm_string => "XXXXX" } + assert_response :success + assert_template :confirm_email + assert_match(/confirmation code has expired or does not exist/, flash[:error]) + end + + ## + # test if testing for a gravatar works + # this happens when the email is actually changed + # which is triggered by the confirmation mail + def test_gravatar_auto_enable + # switch to email that has a gravatar + user = create(:user, :new_email => "test-new@example.com") + stub_gravatar_request(user.new_email, 200) + confirm_string = user.tokens.create.token + # precondition gravatar should be turned off + assert_not user.image_use_gravatar + post user_confirm_email_path, :params => { :confirm_string => confirm_string } + assert_response :redirect + assert_redirected_to :controller => :users, :action => :account, :display_name => user.display_name + assert_match(/Confirmed your change of email address/, flash[:notice]) + # gravatar use should now be enabled + assert User.find(user.id).image_use_gravatar + end + + def test_gravatar_auto_disable + # switch to email without a gravatar + user = create(:user, :new_email => "test-new@example.com", :image_use_gravatar => true) + stub_gravatar_request(user.new_email, 404) + confirm_string = user.tokens.create.token + # precondition gravatar should be turned on + assert user.image_use_gravatar + post user_confirm_email_path, :params => { :confirm_string => confirm_string } + assert_response :redirect + assert_redirected_to :controller => :users, :action => :account, :display_name => user.display_name + assert_match(/Confirmed your change of email address/, flash[:notice]) + # gravatar use should now be disabled + assert_not User.find(user.id).image_use_gravatar + end +end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index 5059ff698..62eb79f0c 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -24,36 +24,6 @@ class UsersControllerTest < ActionDispatch::IntegrationTest { :controller => "users", :action => "save" } ) - assert_routing( - { :path => "/user/username/confirm", :method => :get }, - { :controller => "users", :action => "confirm", :display_name => "username" } - ) - assert_routing( - { :path => "/user/username/confirm", :method => :post }, - { :controller => "users", :action => "confirm", :display_name => "username" } - ) - assert_routing( - { :path => "/user/username/confirm/resend", :method => :get }, - { :controller => "users", :action => "confirm_resend", :display_name => "username" } - ) - - assert_routing( - { :path => "/user/confirm", :method => :get }, - { :controller => "users", :action => "confirm" } - ) - assert_routing( - { :path => "/user/confirm", :method => :post }, - { :controller => "users", :action => "confirm" } - ) - assert_routing( - { :path => "/user/confirm-email", :method => :get }, - { :controller => "users", :action => "confirm_email" } - ) - assert_routing( - { :path => "/user/confirm-email", :method => :post }, - { :controller => "users", :action => "confirm_email" } - ) - assert_routing( { :path => "/user/go_public", :method => :post }, { :controller => "users", :action => "go_public" } @@ -171,7 +141,7 @@ class UsersControllerTest < ActionDispatch::IntegrationTest assert_match(/#{@url}/, register_email.body.to_s) # Check the page - assert_redirected_to :action => "confirm", :display_name => user.display_name + assert_redirected_to :controller => :confirmations, :action => :confirm, :display_name => user.display_name ActionMailer::Base.deliveries.clear end @@ -363,308 +333,6 @@ class UsersControllerTest < ActionDispatch::IntegrationTest ActionMailer::Base.deliveries.clear end - def test_confirm_get - user = build(:user, :pending) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create.token - - get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_response :success - assert_template :confirm - end - - def test_confirm_get_already_confirmed - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create.token - - # Get the confirmation page - get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_response :success - assert_template :confirm - - # Confirm the user - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to welcome_path - - # Now try to get the confirmation page again - get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_response :redirect - assert_redirected_to root_path - end - - def test_confirm_success_no_token_no_referer - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create.token - - post logout_path - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to login_path - assert_match(/Confirmed your account/, flash[:notice]) - end - - def test_confirm_success_good_token_no_referer - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create.token - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to welcome_path - end - - def test_confirm_success_bad_token_no_referer - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create.token - - post logout_path - session_for(create(:user)) - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to login_path - assert_match(/Confirmed your account/, flash[:notice]) - end - - def test_confirm_success_no_token_with_referer - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token - - post logout_path - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to login_path(:referer => new_diary_entry_path) - assert_match(/Confirmed your account/, flash[:notice]) - end - - def test_confirm_success_good_token_with_referer - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to new_diary_entry_path - end - - def test_confirm_success_bad_token_with_referer - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token - - post logout_path - session_for(create(:user)) - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to login_path(:referer => new_diary_entry_path) - assert_match(/Confirmed your account/, flash[:notice]) - end - - def test_confirm_expired_token - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create(:expiry => 1.day.ago).token - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to :action => "confirm" - assert_match(/confirmation code has expired/, flash[:error]) - end - - def test_confirm_already_confirmed - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token - - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to new_diary_entry_path - - post logout_path - - confirm_string = User.find_by(:email => user.email).tokens.create(:referer => new_diary_entry_path).token - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_redirected_to login_path - assert_match(/already been confirmed/, flash[:error]) - end - - def test_confirm_deleted - user = build(:user, :pending) - stub_gravatar_request(user.email) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - confirm_string = User.find_by(:email => user.email).tokens.create.token - - User.find_by(:display_name => user.display_name).update(:status => "deleted") - - # Get the confirmation page - get user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_response :redirect - assert_redirected_to root_path - - # Confirm the user - post user_confirm_path, :params => { :display_name => user.display_name, :confirm_string => confirm_string } - assert_response :not_found - assert_template :no_such_user - end - - def test_confirm_resend_success - user = build(:user, :pending) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - - assert_difference "ActionMailer::Base.deliveries.size", 1 do - perform_enqueued_jobs do - get user_confirm_resend_path(user) - end - end - - assert_response :redirect - assert_redirected_to login_path - assert_match(/sent a new confirmation/, flash[:notice]) - - email = ActionMailer::Base.deliveries.last - - assert_equal user.email, email.to.first - - ActionMailer::Base.deliveries.clear - end - - def test_confirm_resend_no_token - user = build(:user, :pending) - # only complete first half of registration - post user_new_path, :params => { :user => user.attributes } - - assert_no_difference "ActionMailer::Base.deliveries.size" do - perform_enqueued_jobs do - get user_confirm_resend_path(user) - end - end - - assert_response :redirect - assert_redirected_to login_path - assert_match "User #{user.display_name} not found.", flash[:error] - end - - def test_confirm_resend_deleted - user = build(:user, :pending) - post user_new_path, :params => { :user => user.attributes } - post user_save_path, :params => { :read_ct => 1, :read_tou => 1 } - - User.find_by(:display_name => user.display_name).update(:status => "deleted") - - assert_no_difference "ActionMailer::Base.deliveries.size" do - perform_enqueued_jobs do - get user_confirm_resend_path(user) - end - end - - assert_response :redirect - assert_redirected_to login_path - assert_match "User #{user.display_name} not found.", flash[:error] - end - - def test_confirm_resend_unknown_user - assert_no_difference "ActionMailer::Base.deliveries.size" do - perform_enqueued_jobs do - get user_confirm_resend_path(:display_name => "No Such User") - end - end - - assert_response :redirect - assert_redirected_to login_path - assert_match "User No Such User not found.", flash[:error] - end - - def test_confirm_email_get - user = create(:user) - confirm_string = user.tokens.create.token - - get user_confirm_email_path, :params => { :confirm_string => confirm_string } - assert_response :success - assert_template :confirm_email - end - - def test_confirm_email_success - user = create(:user, :new_email => "test-new@example.com") - stub_gravatar_request(user.new_email) - confirm_string = user.tokens.create.token - - post user_confirm_email_path, :params => { :confirm_string => confirm_string } - assert_response :redirect - assert_redirected_to :action => :account, :display_name => user.display_name - assert_match(/Confirmed your change of email address/, flash[:notice]) - end - - def test_confirm_email_already_confirmed - user = create(:user) - confirm_string = user.tokens.create.token - - post user_confirm_email_path, :params => { :confirm_string => confirm_string } - assert_response :redirect - assert_redirected_to :action => :account, :display_name => user.display_name - assert_match(/already been confirmed/, flash[:error]) - end - - def test_confirm_email_bad_token - post user_confirm_email_path, :params => { :confirm_string => "XXXXX" } - assert_response :success - assert_template :confirm_email - assert_match(/confirmation code has expired or does not exist/, flash[:error]) - end - - ## - # test if testing for a gravatar works - # this happens when the email is actually changed - # which is triggered by the confirmation mail - def test_gravatar_auto_enable - # switch to email that has a gravatar - user = create(:user, :new_email => "test-new@example.com") - stub_gravatar_request(user.new_email, 200) - confirm_string = user.tokens.create.token - # precondition gravatar should be turned off - assert_not user.image_use_gravatar - post user_confirm_email_path, :params => { :confirm_string => confirm_string } - assert_response :redirect - assert_redirected_to :action => :account, :display_name => user.display_name - assert_match(/Confirmed your change of email address/, flash[:notice]) - # gravatar use should now be enabled - assert User.find(user.id).image_use_gravatar - end - - def test_gravatar_auto_disable - # switch to email without a gravatar - user = create(:user, :new_email => "test-new@example.com", :image_use_gravatar => true) - stub_gravatar_request(user.new_email, 404) - confirm_string = user.tokens.create.token - # precondition gravatar should be turned on - assert user.image_use_gravatar - post user_confirm_email_path, :params => { :confirm_string => confirm_string } - assert_response :redirect - assert_redirected_to :action => :account, :display_name => user.display_name - assert_match(/Confirmed your change of email address/, flash[:notice]) - # gravatar use should now be disabled - assert_not User.find(user.id).image_use_gravatar - end - def test_terms_new_user user = build(:user, :pending) diff --git a/test/integration/user_creation_test.rb b/test/integration/user_creation_test.rb index 138911bb1..a39e423c0 100644 --- a/test/integration/user_creation_test.rb +++ b/test/integration/user_creation_test.rb @@ -121,7 +121,7 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear end @@ -208,14 +208,14 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear # Go to the confirmation page get "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" post "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :redirect @@ -266,7 +266,7 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear end @@ -361,14 +361,14 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear # Go to the confirmation page get "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" post "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :redirect @@ -420,7 +420,7 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear end @@ -515,14 +515,14 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear # Go to the confirmation page get "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" post "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :redirect @@ -572,7 +572,7 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear end @@ -665,14 +665,14 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear # Go to the confirmation page get "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" post "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :redirect @@ -722,7 +722,7 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear end @@ -815,14 +815,14 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear # Go to the confirmation page get "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" post "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :redirect @@ -873,7 +873,7 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear end @@ -967,14 +967,14 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear # Go to the confirmation page get "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" post "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :redirect @@ -1025,7 +1025,7 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear end @@ -1119,14 +1119,14 @@ class UserCreationTest < ActionDispatch::IntegrationTest # Check the page assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" ActionMailer::Base.deliveries.clear # Go to the confirmation page get "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :success - assert_template "users/confirm" + assert_template "confirmations/confirm" post "/user/#{display_name}/confirm", :params => { :confirm_string => confirm_string } assert_response :redirect