From 104727f889aaf31f917c8243014b161732b6e351 Mon Sep 17 00:00:00 2001 From: Kai Krueger Date: Sat, 13 Oct 2012 00:26:04 -0600 Subject: [PATCH] Trust Google and Yahoo to return valid email addresses Both Google and Yahoo guarantee that the email address they return during the OpenID authentication are emails that they have already verified: http://stackoverflow.com/q/5639419 Therefore special case these OpenID providers and automatically activate the new users account without requiring a separate email verification step. This therefore reduces the signup procedure by one step and makes it easier for new users of these OpenID providers, which cover the majority of users. --- app/controllers/user_controller.rb | 37 ++++++++++++++++++++-- app/models/notifier.rb | 19 ++++++++--- app/views/notifier/signup_confirm.html.erb | 6 ++++ app/views/notifier/signup_confirm.text.erb | 10 ++++++ config/locales/en.yml | 10 ++++-- 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index b61579d92..3fd136554 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -128,12 +128,26 @@ class UserController < ApplicationController @user.terms_seen = true @user.openid_url = nil if @user.openid_url and @user.openid_url.empty? + if (session[:openid_verified]) + openid_verified = session.delete(:openid_verified) + if (openid_verified[:identity_url]) and (openid_verified[:identity_url] == @user.openid_url) and (openid_verified[:email]) and (openid_verified[:email] == @user.email) + # if we have an email from an OpenID provider that we trust to have verified the email for us, then activate the account directly + # without doing our own email verification. + @user.status = "active" + end + end + if @user.save flash[:piwik_goal] = PIWIK_SIGNUP_GOAL if defined?(PIWIK_SIGNUP_GOAL) flash[:notice] = t 'user.new.flash create success message', :email => @user.email - Notifier.signup_confirm(@user, @user.tokens.create(:referer => session.delete(:referer))).deliver - session[:token] = @user.tokens.create.token - redirect_to :action => 'login', :referer => params[:referer] + if @user.status == "active" + Notifier.signup_confirm(@user, nil).deliver + successful_login(@user) + else + Notifier.signup_confirm(@user, @user.tokens.create(:referer => session.delete(:referer))).deliver + session[:token] = @user.tokens.create.token + redirect_to :action => 'login', :referer => params[:referer] + end else render :action => 'new', :referer => params[:referer] end @@ -551,6 +565,9 @@ private # the simple registration protocol. nickname = sreg["nickname"] || ax["http://axschema.org/namePerson/friendly"].first email = sreg["email"] || ax["http://axschema.org/contact/email"].first + + # Check if the openID is from a "trusted" OpenID provider and thus provides a verified email address + session[:openid_verified] = openid_email_verified(identity_url, email) redirect_to :controller => 'user', :action => 'new', :nickname => nickname, :email => email, :openid => identity_url end elsif result.missing? @@ -605,6 +622,20 @@ private end end + def openid_email_verified(openid_url, email) + # OpenID providers Google and Yahoo are guaranteed to return (if at all) an email address that has been verified by + # them already. So we can trust the email addresses to be valid and own by the user without having to verify them our + # selves. + # Store the email in the session to compare agains the user set email address during account creation. + openid_verified = Hash.new + openid_verified[:identity_url] = openid_url + if openid_url.match(/https:\/\/www.google.com\/accounts\/o8\/id?(.*)/) or openid_url.match(/https:\/\/me.yahoo.com\/(.*)/) + openid_verified[:email] = email + end + return openid_verified + + end + ## # process a successful login def successful_login(user) diff --git a/app/models/notifier.rb b/app/models/notifier.rb index 343c3db22..2a5bb15bc 100644 --- a/app/models/notifier.rb +++ b/app/models/notifier.rb @@ -6,11 +6,20 @@ class Notifier < ActionMailer::Base def signup_confirm(user, token) @locale = user.preferred_language_from(I18n.available_locales) - @url = url_for(:host => SERVER_URL, - :controller => "user", :action => "confirm", - :display_name => user.display_name, - :confirm_string => token.token) - + + # If we are passed an email address verification token, create + # the confirumation URL for account activation. + # + # Otherwise the email has already been verified e.g. through + # a trusted openID provider and the account is active and a + # confirmation URL is not needed. + if token + @url = url_for(:host => SERVER_URL, + :controller => "user", :action => "confirm", + :display_name => user.display_name, + :confirm_string => token.token) + end + mail :to => user.email, :subject => I18n.t('notifier.signup_confirm.subject', :locale => @locale) end diff --git a/app/views/notifier/signup_confirm.html.erb b/app/views/notifier/signup_confirm.html.erb index 5b7566fba..74aae6af1 100644 --- a/app/views/notifier/signup_confirm.html.erb +++ b/app/views/notifier/signup_confirm.html.erb @@ -1,11 +1,17 @@

<%= t'notifier.signup_confirm_html.greeting' %>

+<% if @url %>

<%= t'notifier.signup_confirm_html.hopefully_you' %> <%= SERVER_URL %>.

<%= t'notifier.signup_confirm_html.click_the_link' %>

<%= raw(link_to @url, @url) %>

+<% else %> +

<%= t'notifier.signup_confirm_html.created_account' %> + <%= SERVER_URL %>.

+

<%= t'notifier.signup_confirm_html.welcome' %>

+<% end %>

<%= raw(t'notifier.signup_confirm_html.introductory_video', :introductory_video_link => link_to(t('notifier.signup_confirm_html.video_to_openstreetmap'), "http://showmedo.com/videos/video?name=1800000&fromSeriesID=180")) %> <%= raw(t'notifier.signup_confirm_html.more_videos', :more_videos_link => link_to(t('notifier.signup_confirm_html.more_videos_here'), "http://showmedo.com/videos/series?name=mS2P1ZqS6")) %>

diff --git a/app/views/notifier/signup_confirm.text.erb b/app/views/notifier/signup_confirm.text.erb index a53f27dda..274d9f52f 100644 --- a/app/views/notifier/signup_confirm.text.erb +++ b/app/views/notifier/signup_confirm.text.erb @@ -1,12 +1,22 @@ <%= t'notifier.signup_confirm_plain.greeting' %> +<% if @url %> <%= t'notifier.signup_confirm_plain.hopefully_you' %> + <%= SERVER_URL %> <%= t'notifier.signup_confirm_plain.click_the_link_1' %> <%= t'notifier.signup_confirm_plain.click_the_link_2' %> <%= @url %> +<% else %> +<%= t'notifier.signup_confirm_plain.created_account' %> + +<%= SERVER_URL %> + +<%= t'notifier.signup_confirm_plain.welcome_1' %> +<%= t'notifier.signup_confirm_plain.welcome_2' %> +<% end %> <%= t'notifier.signup_confirm_plain.introductory_video' %> diff --git a/config/locales/en.yml b/config/locales/en.yml index bc43ab4bf..07b9a9d4e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1144,14 +1144,18 @@ en: subject: "[OpenStreetMap] GPX Import success" loaded_successfully: loaded successfully with %{trace_points} out of a possible %{possible_points} points. signup_confirm: - subject: "[OpenStreetMap] Confirm your email address" + subject: "[OpenStreetMap] Welcome to OpenStreetMap" signup_confirm_plain: greeting: "Hi there!" hopefully_you: "Someone (hopefully you) would like to create an account over at" + created_account: "You have just created a new account over at" # next two translations run-on : please word wrap appropriately click_the_link_1: "If this is you, welcome! Please click the link below to confirm your" click_the_link_2: "account and read on for more information about OpenStreetMap." - introductory_video: "You can watch an introductory video to OpenStreetMap here:" + # next two translations run-on : please word wrap appropriately + welcome_1: "We would like to welcome you and provide you with some additional information" + welcome_2: "to get you started." + introductory_video: "You can watch an introductory video to OpenStreetMap here:" more_videos: "There are more videos here:" the_wiki: "Get reading about OpenStreetMap on the wiki:" the_wiki_url: "http://wiki.openstreetmap.org/wiki/Beginners%27_Guide" @@ -1168,7 +1172,9 @@ en: signup_confirm_html: greeting: "Hi there!" hopefully_you: "Someone (hopefully you) would like to create an account over at" + created_account: "You have just created a new account over at" click_the_link: "If this is you, welcome! Please click the link below to confirm that account and read on for more information about OpenStreetMap" + welcome: "We would like to welcome you and provide you with some additional information to get you started." introductory_video: "You can watch an %{introductory_video_link}." video_to_openstreetmap: "introductory video to OpenStreetMap" more_videos: "There are %{more_videos_link}." -- 2.43.2