render :update do |page|
page.replace_html "contributorTerms", :partial => "terms"
end
+ elsif using_open_id?
+ # The redirect from the OpenID provider reenters here
+ # again and we need to pass the parameters through to
+ # the open_id_authentication function
+ @user = session.delete(:new_user)
+
+ openid_verify(nil, @user) do |user|
+ end
+
+ if @user.openid_url.nil? or @user.invalid?
+ render :action => 'new'
+ else
+ render :action => 'terms'
+ end
else
+ session[:referer] = params[:referer]
+
@title = t 'user.terms.title'
@user = User.new(params[:user]) if params[:user]
+ if params[:user] and params[:user][:openid_url] and @user.pass_crypt.empty?
+ # We are creating an account with OpenID and no password
+ # was specified so create a random one
+ @user.pass_crypt = ActiveSupport::SecureRandom.base64(16)
+ @user.pass_crypt_confirmation = @user.pass_crypt
+ end
+
if @user
if @user.invalid?
if @user.new_record?
+ # Something is wrong with a new user, so rerender the form
render :action => :new
else
+ # Error in existing user, so go to account settings
flash[:errors] = @user.errors
redirect_to :action => :account, :display_name => @user.display_name
end
elsif @user.terms_agreed?
+ # Already agreed to terms, so just show settings
redirect_to :action => :account, :display_name => @user.display_name
+ elsif params[:user] and params[:user][:openid_url]
+ # Verify OpenID before moving on
+ session[:new_user] = @user
+ openid_verify(params[:user][:openid_url], @user)
end
else
+ # Not logged in, so redirect to the login page
redirect_to :action => :login, :referer => request.request_uri
end
end
if @user.save
flash[:notice] = t 'user.new.flash create success message', :email => @user.email
- Notifier.deliver_signup_confirm(@user, @user.tokens.create(:referer => params[:referer]))
+ Notifier.deliver_signup_confirm(@user, @user.tokens.create(:referer => session.delete(:referer)))
session[:token] = @user.tokens.create.token
redirect_to :action => 'login', :referer => params[:referer]
else
@user.preferred_editor = params[:user][:preferred_editor]
end
- if @user.save
- set_locale
-
- if @user.new_email.nil? or @user.new_email.empty?
- flash[:notice] = t 'user.account.flash update success'
- else
- flash[:notice] = t 'user.account.flash update success confirm needed'
+ @user.openid_url = nil if params[:user][:openid_url].empty?
- begin
- Notifier.deliver_email_confirm(@user, @user.tokens.create)
- rescue
- # Ignore errors sending email
- end
- end
-
- redirect_to :action => "account", :display_name => @user.display_name
+ if params[:user][:openid_url].length > 0 and
+ params[:user][:openid_url] != @user.openid_url
+ # If the OpenID has changed, we want to check that it is a
+ # valid OpenID and one the user has control over before saving
+ # it as a password equivalent for the user.
+ session[:new_user] = @user
+ openid_verify(params[:user][:openid_url], @user)
+ else
+ update_user(@user)
+ end
+ elsif using_open_id?
+ # The redirect from the OpenID provider reenters here
+ # again and we need to pass the parameters through to
+ # the open_id_authentication function
+ @user = session.delete(:new_user)
+ openid_verify(nil, @user) do |user|
+ update_user(user)
end
else
if flash[:errors]
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
- redirect_to :controller => 'site', :action => 'index' if session[:user]
+ @referer = params[:referer] || session[:referer]
+
+ if session[:user]
+ # 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'
+ elsif not params['openid'].nil?
+ flash.now[:notice] = t 'user.new.openid association'
+ end
end
def login
- @title = t 'user.login.title'
+ if params[:username] or using_open_id?
+ session[:remember_me] ||= params[:remember_me]
+ session[:referer] ||= params[:referer]
- 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]
-
- target = params[:referer] || url_for(:controller => :site, :action => :index)
-
- # The user is logged in, so decide where to send them:
- #
- # - If they haven't seen the contributor terms, send them there.
- # - If they have a block on them, show them that.
- # - If they were referred to the login, send them back there.
- # - Otherwise, send them to the home page.
- if REQUIRE_TERMS_SEEN and not user.terms_seen
- redirect_to :controller => :user, :action => :terms, :referer => target
- elsif user.blocked_on_view
- redirect_to user.blocked_on_view, :referer => target
- else
- redirect_to target
- end
- elsif user = User.authenticate(:username => email_or_display_name, :password => pass, :pending => true)
- flash.now[:error] = t 'user.login.account not active', :reconfirm => url_for(:action => 'confirm_resend', :display_name => user.display_name)
- elsif User.authenticate(:username => email_or_display_name, :password => pass, :suspended => true)
- webmaster = link_to t('user.login.webmaster'), "mailto:webmaster@openstreetmap.org"
- flash.now[:error] = t 'user.login.account suspended', :webmaster => webmaster
+ if using_open_id?
+ openid_authentication(params[:openid_url])
else
- flash.now[:error] = t 'user.login.auth failure'
+ password_authentication(params[:username], params[:password])
end
elsif flash[:notice].nil?
flash.now[:notice] = t 'user.login.notice'
if token
token.destroy
end
- session[:token] = nil
+ session.delete(:token)
end
- session[:user] = nil
+ session.delete(:user)
session_expires_automatically
if params[:referer]
redirect_to params[:referer]
private
+ ##
+ # handle password authentication
+ def password_authentication(username, password)
+ if user = User.authenticate(:username => username, :password => password)
+ successful_login(user)
+ elsif user = User.authenticate(:username => username, :password => password, :pending => true)
+ failed_login t('user.login.account not active', :reconfirm => url_for(:action => 'confirm_resend', :display_name => user.display_name))
+ elsif User.authenticate(:username => username, :password => password, :suspended => true)
+ webmaster = link_to t('user.login.webmaster'), "mailto:webmaster@openstreetmap.org"
+ failed_login t('user.login.account suspended', :webmaster => webmaster)
+ else
+ failed_login t('user.login.auth failure')
+ end
+ end
+
+ ##
+ # handle OpenID authentication
+ def openid_authentication(openid_url)
+ # If we don't appear to have a user for this URL then ask the
+ # provider for some extra information to help with signup
+ if openid_url and User.find_by_openid_url(openid_url)
+ required = nil
+ else
+ required = [:nickname, :email, "http://axschema.org/namePerson/friendly", "http://axschema.org/contact/email"]
+ end
+
+ # Start the authentication
+ authenticate_with_open_id(openid_expand_url(openid_url), :required => required) do |result, identity_url, sreg, ax|
+ 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.
+ #
+ # For example, you can simply enter yahoo.com in the login box rather
+ # than a user specific url. Only once it comes back from the provider
+ # provider do we know the unique address for the user.
+ if user = User.find_by_openid_url(identity_url)
+ case user.status
+ when "pending" then
+ failed_login t('user.login.account not active')
+ when "active", "confirmed" then
+ successful_login(user)
+ when "suspended" then
+ webmaster = link_to t('user.login.webmaster'), "mailto:webmaster@openstreetmap.org"
+ failed_login t('user.login.account suspended', :webmaster => webmaster)
+ else
+ failed_login t('user.login.auth failure')
+ end
+ else
+ # We don't have a user registered to this OpenID, so 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.
+ nickname = sreg["nickname"] || ax["http://axschema.org/namePerson/friendly"]
+ email = sreg["email"] || ax["http://axschema.org/contact/email"]
+ redirect_to :controller => 'user', :action => 'new', :nickname => nickname, :email => email, :openid => identity_url
+ end
+ elsif result.missing?
+ failed_login t('user.login.openid missing provider')
+ elsif result.invalid?
+ failed_login t('user.login.openid invalid')
+ else
+ failed_login t('user.login.auth failure')
+ end
+ end
+ end
+
+ ##
+ # verify an OpenID URL
+ def openid_verify(openid_url, user)
+ user.openid_url = openid_url
+
+ authenticate_with_open_id(openid_expand_url(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.
+ #
+ # For example, you can simply enter yahoo.com in the login box rather
+ # than a user specific url. Only once it comes back from the provider
+ # provider do we know the unique address for the user.
+ user.openid_url = identity_url
+ yield user
+ elsif result.missing?
+ flash.now[:error] = t 'user.login.openid missing provider'
+ elsif result.invalid?
+ flash.now[:error] = t 'user.login.openid invalid'
+ else
+ flash.now[:error] = t 'user.login.auth failure'
+ end
+ end
+ end
+
+ ##
+ # special case some common OpenID providers by applying heuristics to
+ # try and come up with the correct URL based on what the user entered
+ def openid_expand_url(openid_url)
+ if openid_url.nil?
+ return nil
+ elsif openid_url.match(/(.*)gmail.com(\/?)$/) or openid_url.match(/(.*)googlemail.com(\/?)$/)
+ # Special case gmail.com as it is potentially a popular OpenID
+ # provider and, unlike yahoo.com, where it works automatically, Google
+ # have hidden their OpenID endpoint somewhere obscure this making it
+ # somewhat less user friendly.
+ return 'https://www.google.com/accounts/o8/id'
+ else
+ return openid_url
+ end
+ end
+
+ ##
+ # process a successful login
+ def successful_login(user)
+ session[:user] = user.id
+ session_expires_after 1.month if session[:remember_me]
+
+ target = session[:referer] || url_for(:controller => :site, :action => :index)
+
+ # The user is logged in, so decide where to send them:
+ #
+ # - If they haven't seen the contributor terms, send them there.
+ # - If they have a block on them, show them that.
+ # - If they were referred to the login, send them back there.
+ # - Otherwise, send them to the home page.
+ if REQUIRE_TERMS_SEEN and not user.terms_seen
+ redirect_to :controller => :user, :action => :terms, :referer => target
+ elsif user.blocked_on_view
+ redirect_to user.blocked_on_view, :referer => target
+ else
+ redirect_to target
+ end
+
+ session.delete(:remember_me)
+ session.delete(:referer)
+ end
+
+ ##
+ # process a failed login
+ def failed_login(message)
+ flash[:error] = message
+
+ redirect_to :action => 'login', :referer => session[:referer]
+
+ session.delete(:remember_me)
+ session.delete(:referer)
+ end
+
+ ##
+ # update a user's details
+ def update_user(user)
+ if user.save
+ set_locale
+
+ if user.new_email.nil? or user.new_email.empty?
+ flash.now[:notice] = t 'user.account.flash update success'
+ else
+ flash.now[:notice] = t 'user.account.flash update success confirm needed'
+
+ begin
+ Notifier.deliver_email_confirm(user, user.tokens.create)
+ rescue
+ # Ignore errors sending email
+ end
+ end
+ end
+ end
+
##
# require that the user is a administrator, or fill out a helpful error message
# and return them to the user page.
<div id="login_wrapper">
+
<div id="login_login">
<h1><%= t 'user.login.heading' %></h1>
- <p><%= t 'user.login.already have' %></p>
-
- <% form_tag :action => 'login' do %>
+ <% form_tag({ :action => "login" }, { :id => "login_form" }) do %>
<%= hidden_field_tag('referer', h(params[:referer])) %>
+
+ <p><%= t 'user.login.with username' %></p>
+
<table id="loginForm">
- <tr><td class="fieldName"><%= t 'user.login.email or username' %></td><td><%= text_field('user', 'email',{:value => "", :size => 28, :maxlength => 255, :tabindex => 1}) %></td></tr>
+ <tr><td class="fieldName"><%= t 'user.login.email or username' %></td><td><%= text_field('user', 'email',{:value => params[:username], :size => 28, :maxlength => 255, :tabindex => 1}) %></td></tr>
<tr><td class="fieldName"><%= t 'user.login.password' %></td><td><%= password_field('user', 'password',{:value => "", :size => 28, :maxlength => 255, :tabindex => 2}) %> <span class="minorNote">(<%= link_to t('user.login.lost password link'), :controller => 'user', :action => 'lost_password' %>)</span></td></tr>
<tr><td class="fieldName"><label for="remember_me"><%= t 'user.login.remember' %></label></td><td><%= check_box_tag "remember_me", "yes", false, :tabindex => 3 %></td></tr>
</table>
<%= submit_tag t('user.login.login_button'), :tabindex => 3 %>
+
+ <br clear="all" />
+
+ <p><%= t 'user.login.with openid' %></p>
+
+ <table id="login_openid_buttons_wide">
+ <tr>
+ <td>
+ <%=
+ link_to_function(image_tag("openid_large.png", :alt => t("user.login.openid_providers.openid.title")), nil, :title => t("user.login.openid_providers.openid.title")) do |page|
+ page[:login_form][:openid_url].value = "http://"
+ page[:login_openid_buttons_wide].hide
+ page[:login_openid_url].show
+ page[:login_openid_submit].show
+ end
+ %>
+ </td>
+ <td><%= openid_button "google", "gmail.com" %></td>
+ <td><%= openid_button "yahoo", "me.yahoo.com" %></td>
+ </tr>
+ <tr>
+ <td><%= openid_button "myopenid", "myopenid.com" %></td>
+ <td><%= openid_button "wordpress", "wordpress.com" %></td>
+ <td><%= openid_button "aol", "aol.com" %></td>
+ </tr>
+ </table>
+
+ <table id="login_openid_buttons_narrow">
+ <tr>
+ <td>
+ <%=
+ link_to_function(image_tag("openid_large.png", :alt => t("user.login.openid_providers.openid.title")), nil, :title => t("user.login.openid_providers.openid.title")) do |page|
+ page[:login_form][:openid_url].value = "http://"
+ page[:login_openid_buttons_narrow].hide
+ page[:login_openid_url].show
+ page[:login_openid_submit].show
+ end
+ %>
+ </td>
+ <td><%= openid_button "google", "gmail.com" %></td>
+ </tr>
+ <tr>
+ <td><%= openid_button "yahoo", "me.yahoo.com" %></td>
+ <td><%= openid_button "myopenid", "myopenid.com" %></td>
+ </tr>
+ <tr>
+ <td><%= openid_button "wordpress", "wordpress.com" %></td>
+ <td><%= openid_button "aol", "aol.com" %></td>
+ </tr>
+ </table>
+
+ <table>
+ <tr id="login_openid_url">
+ <td class="fieldName nowrap">
+ <%= t 'user.login.openid', :logo => openid_logo %>
+ </td>
+ <td>
+ <%= text_field_tag("openid_url", "", { :size => 28, :maxlength => 255, :tabindex => 3, :class => "openid_url" }) %>
+ <span class="minorNote">(<a href="<%= t 'user.account.openid.link' %>" target="_new"><%= t 'user.account.openid.link text' %></a>)</span>
+ </td>
+ </tr>
+ <tr>
+ <td class="fieldName nowrap" id="remember_me_label"><label for="remember_me"><%= t 'user.login.remember' %></label></td>
+ <td width="100%"><%= check_box_tag "remember_me", "yes", false, :tabindex => 5 %></td>
+ </tr>
+ </table>
+
+ <%= submit_tag t('user.login.login_button'), :tabindex => 6, :id => "login_openid_submit" %>
<% end %>
+
<br clear="all" />
</div>
+
<div id="login_signup">
<h2><%= t 'user.login.new to osm' %></h2>
<p><%= t 'user.login.to make changes' %></p>
<p><%= t 'user.login.create account minute' %></p>
<p><%= button_to t('user.login.register now'), :action => :new, :referer => params[:referer] %></p>
- <br clear="all" />
+
+ <br clear="both">
</div>
+
</div>
+
+<%=
+ update_page_tag do |page|
+ page[:login_openid_url].hide
+ page[:login_openid_submit].hide
+ end
+%>
<ul id="contributors">
<li><strong>Australia</strong>: Contains suburb data based
on Australian Bureau of Statistics data.</li>
+ <li><strong>Austria</strong>: Contains data from
+ <a href="http://data.wien.gv.at/">Stadt Wien</a> under
+ <a href="http://creativecommons.org/licenses/by/3.0/at/deed.de">CC-BY</a>.</li>
<li><strong>Canada</strong>: Contains data from
GeoBase®, GeoGratis (© Department of Natural
Resources Canada), CanVec (© Department of Natural
login:
title: "Login"
heading: "Login"
- please login: "Please login or %{create_user_link}."
- create_account: "create an account"
email or username: "Email Address or Username:"
password: "Password:"
+ openid: "%{logo} OpenID:"
remember: "Remember me:"
lost password link: "Lost your password?"
login_button: "Login"
register now: Register now
- already have: Already have an OpenStreetMap account? Please login.
+ with username: "Already have an OpenStreetMap account? Please login with your username and password:"
+ with openid: "Alternatively please use your OpenID to login:"
new to osm: New to OpenStreetMap?
to make changes: To make changes to the OpenStreetMap data, you must have an account.
create account minute: Create an account. It only takes a minute.
webmaster: webmaster
auth failure: "Sorry, could not log in with those details."
notice: "<a href=\"http://www.osmfoundation.org/wiki/License/We_Are_Changing_The_License\">Find out more about OpenStreetMap's upcoming license change</a> (<a href=\"http://wiki.openstreetmap.org/wiki/ODbL/We_Are_Changing_The_License\">translations</a>) (<a href=\"http://wiki.openstreetmap.org/wiki/Talk:ODbL/Upcoming\">discussion</a>)"
+ openid missing provider: "Sorry, could not contact your OpenID provider"
+ openid invalid: "Sorry, your OpenID seems to be malformed"
+ openid_logo_alt: "Log in with an OpenID"
+ openid_providers:
+ openid:
+ title: Login with OpenID
+ alt: Login with an OpenID URL
+ google:
+ title: Login with Google
+ alt: Login with a Google OpenID
+ yahoo:
+ title: Login with Yahoo
+ alt: Login with a Yahoo OpenID
+ myopenid:
+ title: Login with myOpenID
+ alt: Login with a myOpenID OpenID
+ wordpress:
+ title: Login with Wordpress
+ alt: Login with a Wordpress OpenID
+ aol:
+ title: Login with AOL
+ alt: Login with an AOL OpenID
logout:
title: "Logout"
heading: "Logout from OpenStreetMap"
not displayed publicly: 'Not displayed publicly (see <a href="http://wiki.openstreetmap.org/wiki/Privacy_Policy" title="wiki privacy policy including section on email addresses">privacy policy</a>)'
display name: "Display Name:"
display name description: "Your publicly displayed username. You can change this later in the preferences."
+ openid: "%{logo} OpenID:"
password: "Password:"
confirm password: "Confirm Password:"
+ use openid: "Alternatively, use %{logo} OpenID to login"
+ openid no password: "With OpenID a password is not required, but some extra tools or server may still need one."
+ openid association: |
+ <p>Your OpenID is not associated with a OpenStreetMap account yet.</p>
+ <ul>
+ <li>If you are new to OpenStreetMap, please create a new account using the form below.</li>
+ <li>
+ If you already have an account, you can login to your account
+ using your username and password and then associate the account
+ with your OpenID in your user settings.
+ </li>
+ </ul>
continue: Continue
flash create success message: "Thanks for signing up. We've sent a confirmation note to %{email} and as soon as you confirm your account you'll be able to get mapping.<br /><br />If you use an antispam system which sends confirmation requests then please make sure you whitelist webmaster@openstreetmap.org as we are unable to reply to any confirmation requests."
terms accepted: "Thanks for accepting the new contributor terms!"
current email address: "Current Email Address:"
new email address: "New Email Address:"
email never displayed publicly: "(never displayed publicly)"
+ openid:
+ openid: "OpenID:"
+ link: "http://wiki.openstreetmap.org/wiki/OpenID"
+ link text: "what is this?"
public editing:
heading: "Public editing:"
enabled: "Enabled. Not anonymous and can edit data."