From: Tom Hughes Date: Mon, 19 Apr 2010 23:41:03 +0000 (+0100) Subject: Merge branch 'master' into openid X-Git-Tag: live~6391 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/d36fab2913d10bef4eae2cee7c34875f20311af9 Merge branch 'master' into openid Conflicts: app/controllers/user_controller.rb app/views/user/login.html.erb config/locales/en.yml --- d36fab2913d10bef4eae2cee7c34875f20311af9 diff --cc app/controllers/user_controller.rb index 97e184b59,9551ac6d8..428a8b90c --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@@ -173,88 -91,6 +173,90 @@@ if (!params[:user][:openid_url].nil? an end end + def openid_specialcase_mapping(openid_url) + #Special case gmail.com, as it is pontentially a popular OpenID provider and unlike + #yahoo.com, where it works automatically, Google have hidden their OpenID endpoint + #somewhere obscure making it less userfriendly. + if (openid_url.match(/(.*)gmail.com(\/?)$/) or openid_url.match(/(.*)googlemail.com(\/?)$/) ) + return 'https://www.google.com/accounts/o8/id' + end + + return nil + end + + def openid_verify(openid_url,account_create) + authenticate_with_open_id(openid_url) do |result, identity_url| + if result.successful? + #We need to use the openid url passed back from the OpenID provider + #rather than the one supplied by the user, as these can be different. + #e.g. one can simply enter yahoo.com in the login box, i.e. no user specific url + #only once it comes back from the OpenID provider do we know the unique address for + #the user. + @user = session[:new_usr] unless @user #this is used for account creation when the user is not yet in the database + @user.openid_url = identity_url + elsif result.missing? + mapped_id = openid_specialcase_mapping(openid_url) + if mapped_id + openid_verify(mapped_id, account_create) + else + flash.now[:error] = t 'user.login.openid missing provider' + end + elsif result.invalid? + flash.now[:error] = t 'user.login.openid invalid' + else + flash.now[:error] = t 'user.login.auth failure' + end + end + end + + def open_id_authentication(openid_url) + #TODO: only ask for nickname and email, if we don't already have a user for that openID, in which case + #email and nickname are already filled out. I don't know how to do that with ruby syntax though, as we + #don't want to duplicate the do block + #On the other hand it also doesn't matter too much if we ask every time, as the OpenID provider should + #remember these results, and shouldn't repromt the user for these data each time. + authenticate_with_open_id(openid_url, :return_to => request.protocol + request.host_with_port + '/login?referer=' + params[:referer], :optional => [:nickname, :email]) do |result, identity_url, registration| + if result.successful? + #We need to use the openid url passed back from the OpenID provider + #rather than the one supplied by the user, as these can be different. + #e.g. one can simply enter yahoo.com in the login box, i.e. no user specific url + #only once it comes back from the OpenID provider do we know the unique address for + #the user. + user = User.find_by_openid_url(identity_url) + if user + if user.visible? and user.active? + session[:user] = user.id + session_expires_after 1.month if session[:remember] + else + user = nil + flash.now[:error] = t 'user.login.account not active' + end + else + #We don't have a user registered to this OpenID. Redirect to the create account page + #with username and email filled in if they have been given by the OpenID provider through + #the simple registration protocol + redirect_to :controller => 'user', :action => 'new', :nickname => registration['nickname'], :email => registration['email'], :openid => identity_url + end + else if result.missing? + #Try and apply some heuristics to make common cases more userfriendly + mapped_id = openid_specialcase_mapping(openid_url) + if mapped_id + open_id_authentication(mapped_id) + else + flash.now[:error] = t 'user.login.openid missing provider' + end + else if result.invalid? + flash.now[:error] = t 'user.login.openid invalid' + else + flash.now[:error] = t 'user.login.auth failure' + end + end + end + end ++ ++ user + end + def go_public @user.data_public = true @user.save @@@ -310,60 -146,39 +312,54 @@@ def new @title = t 'user.new.title' - # The user is logged in already, so don't show them the signup page, instead - # send them to the home page + # The user is logged in already, so don't show them the signup + # page, instead send them to the home page redirect_to :controller => 'site', :action => 'index' if session[:user] + + @nickname = params['nickname'] + @email = params['email'] + @openID = params['openid'] end def login + @title = t 'user.login.title' - #The redirect from the OpenID provider reenters here again - if params[:user] - email_or_display_name = params[:user][:email] - pass = params[:user][:password] - user = User.authenticate(:username => email_or_display_name, :password => pass) - - if user - session[:user] = user.id - session_expires_after 1.month if params[:remember_me] - - # The user is logged in, if the referer param exists, redirect - # them to that unless they've also got a block on them, in - # which case redirect them to the block so they can clear it. - if user.blocked_on_view - redirect_to user.blocked_on_view, :referrer => params[:referrer] - elsif params[:referer] - redirect_to params[:referer] ++ #The redirect from the OpenID provider reenters here again + #and we need to pass the parameters through to the + # open_id_authentication function + if params[:open_id_complete] - open_id_authentication('') - end - - if params[:user] and session[:user].nil? - if !params[:user][:openid_url].nil? and !params[:user][:openid_url].empty? - session[:remember] = params[:remember_me] - open_id_authentication(params[:user][:openid_url]) ++ user = open_id_authentication('') ++ elsif params[:user] ++ if !params[:user][:openid_url].nil? and !params[:user][:openid_url].empty? ++ session[:remember] = params[:remember_me] ++ user = open_id_authentication(params[:user][:openid_url]) + else - email_or_display_name = params[:user][:email] - pass = params[:user][:password] - user = User.authenticate(:username => email_or_display_name, :password => pass) - if user - session[:user] = user.id - session_expires_after 1.month if params[:remember_me] - elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true) - flash.now[:error] = t 'user.login.account not active' - else - flash.now[:error] = t 'user.login.auth failure' - end - end ++ email_or_display_name = params[:user][:email] ++ pass = params[:user][:password] ++ ++ if user = User.authenticate(:username => email_or_display_name, :password => pass) ++ session[:user] = user.id ++ session_expires_after 1.month if params[:remember_me] ++ elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true) ++ flash.now[:error] = t 'user.login.account not active' + else - redirect_to :controller => 'site', :action => 'index' ++ flash.now[:error] = t 'user.login.auth failure' + end - elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true) - flash.now[:error] = t 'user.login.account not active' ++ end + end + - if session[:user] - # The user is logged in, if the referer param exists, redirect them to that - # unless they've also got a block on them, in which case redirect them to - # the block so they can clear it. - user = User.find(session[:user]) - block = user.blocked_on_view - if block - redirect_to block, :referrer => params[:referrer] ++ if user ++ # The user is logged in, if the referer param exists, redirect ++ # them to that unless they've also got a block on them, in ++ # which case redirect them to the block so they can clear it. ++ if user.blocked_on_view ++ redirect_to user.blocked_on_view, :referrer => params[:referrer] + elsif params[:referer] + redirect_to params[:referer] else - flash.now[:error] = t 'user.login.auth failure' + redirect_to :controller => 'site', :action => 'index' end - return end - - @title = t 'user.login.title' end def logout diff --cc app/views/user/account.html.erb index c20f3526c,85e9aebef..badcc1249 --- a/app/views/user/account.html.erb +++ b/app/views/user/account.html.erb @@@ -23,12 -24,8 +23,12 @@@ <%= t 'user.new.confirm password' %> - <%= f.password_field :pass_crypt_confirmation, {:value => '', :size => 30, :maxlength => 255} %> + <%= f.password_field :pass_crypt_confirmation, {:value => '', :size => 30, :maxlength => 255, :autocomplete => :off} %> + + <%= t 'user.account.openid.openid' %> + <%= f.text_field :openid_url %> (<%= t 'user.account.openid.link text' %>) + <%= t 'user.account.public editing.heading' %> diff --cc app/views/user/login.html.erb index 269bbc0cc,cf7f4a819..46e7f7b8b --- a/app/views/user/login.html.erb +++ b/app/views/user/login.html.erb @@@ -5,13 -5,10 +5,12 @@@ <% form_tag :action => 'login' do %> <%= hidden_field_tag('referer', h(params[:referer])) %> - - - - - - - - + - - - - ++ ++ ++ ++ ++ ++
<%= t 'user.login.email or username' %><%= text_field('user', 'email',{:size => 28, :maxlength => 255, :tabindex => 1}) %>
<%= t 'user.login.password' %><%= password_field('user', 'password',{:size => 28, :maxlength => 255, :tabindex => 2}) %> (<%= link_to t('user.login.lost password link'), :controller => 'user', :action => 'lost_password' %>)

<%= t 'user.login.alternatively' %>

<%= t 'user.login.openid' %><%= text_field('user', 'openid_url',{:size => 28, :maxlength => 255, :tabindex => 3}) %> (<%= t 'user.account.openid.link text' %>)
 
 
<%= check_box_tag "remember_me", "yes", false, :tabindex => 3 %><%= submit_tag t('user.login.login_button'), :tabindex => 3 %>
<%= t 'user.login.email or username' %><%= text_field('user', 'email',{:value => "", :size => 28, :maxlength => 255, :tabindex => 1}) %>
<%= t 'user.login.password' %><%= password_field('user', 'password',{:value => "", :size => 28, :maxlength => 255, :tabindex => 2}) %> (<%= link_to t('user.login.lost password link'), :controller => 'user', :action => 'lost_password' %>)
<%= check_box_tag "remember_me", "yes", false, :tabindex => 3 %>
 
<%= submit_tag t('user.login.login_button'), :tabindex => 3 %>
<%= t 'user.login.password' %><%= password_field('user', 'password',{:value => "", :size => 28, :maxlength => 255, :tabindex => 2}) %> (<%= link_to t('user.login.lost password link'), :controller => 'user', :action => 'lost_password' %>)

<%= t 'user.login.alternatively' %>

<%= t 'user.login.openid' %><%= text_field('user', 'openid_url',{:size => 28, :maxlength => 255, :tabindex => 3}) %> (<%= t 'user.account.openid.link text' %>)
 
 
<%= check_box_tag "remember_me", "yes", false, :tabindex => 3 %><%= submit_tag t('user.login.login_button'), :tabindex => 3 %>
<% end %> diff --cc config/environment.rb index 70a1ddbd5,539af83b2..01115ba97 --- a/config/environment.rb +++ b/config/environment.rb @@@ -52,8 -52,8 +52,9 @@@ Rails::Initializer.run do |config config.gem 'rmagick', :lib => 'RMagick' config.gem 'oauth', :version => '>= 0.3.6' config.gem 'httpclient' + config.gem 'ruby-openid', :lib => 'openid', :version => '>=2.0.4' config.gem 'SystemTimer', :version => '>= 1.1.3', :lib => 'system_timer' + config.gem 'sanitize' # Only load the plugins named here, in the order given. By default, all plugins # in vendor/plugins are loaded in alphabetical order. diff --cc config/locales/en.yml index b358cf8d3,8699d600c..2df80cd1d --- a/config/locales/en.yml +++ b/config/locales/en.yml @@@ -1351,15 -1362,15 +1362,20 @@@ en create_account: "create an account" email or username: "Email Address or Username:" password: "Password:" + openid: "OpenID:" + openid description: "Use your OpenID to login" + alternatively: "Alternatively" + remember: "Remember me:" lost password link: "Lost your password?" login_button: "Login" account not active: "Sorry, your account is not active yet.
Please click on the link in the account confirmation email to activate your account." auth failure: "Sorry, could not log in with those details." + openid missing provider: "Sorry, could not contact your OpenID provider" + openid invalid: "Sorry, your OpenID seems misformed" + logout: + title: "Logout" + heading: "Logout from OpenStreetMap" + logout_button: "Logout" lost_password: title: "Lost password" heading: "Forgotten Password?"