]> git.openstreetmap.org Git - rails.git/commitdiff
Merge branch 'master' into openid
authorTom Hughes <tom@compton.nu>
Tue, 11 May 2010 20:22:43 +0000 (21:22 +0100)
committerTom Hughes <tom@compton.nu>
Tue, 11 May 2010 20:22:43 +0000 (21:22 +0100)
Conflicts:
app/controllers/user_controller.rb
app/views/user/new.html.erb
config/locales/en.yml
public/stylesheets/common.css

1  2 
app/controllers/user_controller.rb
app/views/user/new.html.erb
app/views/user/terms.html.erb
config/locales/en.yml
db/migrate/053_add_open_id_authentication_tables.rb
public/stylesheets/common.css

index 0144f69b61c2ba58c450bbe95fe656fef7b3a0ee,e07b65af76502278deb69b98c62283bc76f20e39..0459d9a534eb6a581600364ee49e2c6a363eea5a
@@@ -18,55 -18,45 +18,82 @@@ class UserController < ApplicationContr
  
    cache_sweeper :user_sweeper, :only => [:account, :set_status, :delete]
  
-   def save
+   def terms
      @title = t 'user.new.title'
 -    @user = User.new(params[:user])
 -
+     @legale = params[:legale] || OSM.IPToCountry(request.remote_ip) || APP_CONFIG['default_legale']
+     @text = OSM.legal_text_for_country(@legale)
  
-     if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"})
-       render :action => 'new'
-     else
-       if params[:open_id_complete] 
-         # 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|
-           create_user(user)
-         end
-       else
-         session[:referer] = params[:referer]
+     if request.xhr?
+       render :update do |page|
+         page.replace_html "contributorTerms", :partial => "terms"
+       end
 -    elsif @user.invalid?
 -      render :action => 'new'
++    elsif params[:open_id_complete] 
++      # 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)
 +
-         @user = User.new(params[: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]
 +
-         @user.status = "pending"
-         @user.data_public = true
-         @user.description = "" if @user.description.nil?
-         @user.creation_ip = request.remote_ip
-         @user.languages = request.user_preferred_languages
++      @user = User.new(params[:user])
++      @user.openid_url = nil
 +
-         if 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 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.valid?
-           if params[:user][:openid_url].nil? or
-              params[:user][:openid_url].empty?
-             # No OpenID so just save
-             create_user(@user)
-           else
-             # Verify OpenID before saving
-             session[:new_user] = @user
-             openid_verify(params[:user][:openid_url], @user)
-           end
++      if @user.valid?
++        if params[:user][:openid_url].nil? or
++            params[:user][:openid_url].empty?
++          # No OpenID so just move on to the terms
++          render :action => 'terms'
++        else
++          # Verify OpenID before moving on
++          session[:new_user] = @user
++          openid_verify(params[:user][:openid_url], @user)
 +        end
++      else
++        # Something is wrong, so rerender the form
++        render :action => 'new'
 +      end
+     end
+   end
+   def save
+     @title = t 'user.new.title'
  
-       # Render the signup page unless we have already been
-       # redirected or have managed to save the user
-       if response.location.nil? and  @user.new_record?
-         render :action => "new"
+     if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"})
+       render :action => 'new'
+     elsif params[:decline]
+       redirect_to t('user.terms.declined')
+     else
+       @user = User.new(params[:user])
+       @user.status = "pending"
+       @user.data_public = true
+       @user.description = "" if @user.description.nil?
+       @user.creation_ip = request.remote_ip
+       @user.languages = request.user_preferred_languages
+       @user.terms_agreed = Time.now.getutc
+       if @user.save
+         flash[:notice] = t 'user.new.flash create success message'
 -        Notifier.deliver_signup_confirm(@user, @user.tokens.create(:referer => params[:referer]))
++        Notifier.deliver_signup_confirm(@user, @user.tokens.create(:referer => session.delete(:referer)))
+         redirect_to :action => 'login'
+       else
+         render :action => 'new'
        end
      end
    end
      @title = t 'user.account.title'
      @tokens = @user.oauth_tokens.find :all, :conditions => 'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null'
  
 -    if params[:user] and params[:user][:display_name] and params[:user][:description]
 +    if params[:open_id_complete]
 +      # 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
 +    elsif params[:user] and params[:user][:display_name] and params[:user][:description]
        @user.display_name = params[:user][:display_name]
        @user.new_email = params[:user][:new_email]
  
        @user.home_lat = params[:user][:home_lat]
        @user.home_lon = params[:user][:home_lon]
  
 -      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
 -      end
 -    else
 -      if flash[:errors]
 -        flash[:errors].each do |attr,msg|
 -          attr = "new_email" if attr == "email"
 -          @user.errors.add(attr,msg)
 -        end
 +      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
      end
    end
  
    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[:user]
 -      email_or_display_name = params[:user][:email]
 -      pass = params[:user][:password]
 -      user = User.authenticate(:username => email_or_display_name, :password => pass)
 +    if request.post?
 +      session[:remember_me] ||= params[:remember_me]
 +      session[:referer] ||= params[:referer]
  
 -      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]
 -        else
 -          redirect_to :controller => 'site', :action => 'index'
 -        end
 -      elsif User.authenticate(:username => email_or_display_name, :password => pass, :pending => true)
 -        flash.now[:error] = t 'user.login.account not active'
 -      elsif User.authenticate(:username => email_or_display_name, :password => pass, :suspended => true)
 -        flash.now[:error] = t 'user.login.account suspended'
 +      if using_open_id?(params[:openid_url])
 +        openid_authentication(params[:openid_url])
        else
 -        flash.now[:error] = t 'user.login.auth failure'
 +        password_authentication(params[:username], params[:password])
        end
 +    else
 +      @title = t 'user.login.title'
      end
    end
  
  
  private
  
-   ##
-   # save a new user
-   def create_user(user)
-     if user.save
-       flash[:notice] = t 'user.new.flash create success message'
-       Notifier.deliver_signup_confirm(user, user.tokens.create(:referer => session.delete(:referer)))
-       redirect_to :action => 'login'
-     end
-   end
 +  ##
 +  # handle password authentication
 +  def password_authentication(username, password)
 +    if user = User.authenticate(:username => username, :password => password)
 +      successful_login(user)
 +    elsif User.authenticate(:username => username, :password => password, :pending => true)
 +      failed_login t('user.login.account not active')
 +    elsif User.authenticate(:username => username, :password => password, :suspended => true)
 +      failed_login t('user.login.account suspended')
 +    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)
 +      optional = nil
 +    else
 +      optional = [:nickname, :email]
 +    end
 +
 +    # Start the authentication
 +    authenticate_with_open_id(openid_url, :optional => optional) 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.
 +        #
 +        # 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 failed_login t('user.login.account suspended')
 +            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.
 +          redirect_to :controller => 'user', :action => 'new', :nickname => registration['nickname'], :email => registration['email'], :openid => identity_url
 +        end
 +      elsif result.missing?
 +        # Try and apply some heuristics to make common cases more user friendly
 +        if openid_url = openid_alternate_url(openid_url)
 +          openid_authentication(openid_url)
 +        else
 +          failed_login t('user.login.openid missing provider')
 +        end
 +      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_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?
 +        # Try and apply some heuristics to make common cases more user friendly
 +        if openid_url = openid_alternate_url(openid_url)
 +          openid_verify(openid_url, user)
 +        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
 +
 +  ##
 +  # special case some common OpenID providers by applying heuristics
 +  # to try and come up with an alternate URL if the supplied one fails
 +  def openid_alternate_url(openid_url)
 +    # 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.
 +    if openid_url.match(/(.*)gmail.com(\/?)$/) or openid_url.match(/(.*)googlemail.com(\/?)$/)
 +      return 'https://www.google.com/accounts/o8/id'
 +    else
 +      return nil
 +    end
 +  end  
 +
 +  ##
 +  # process a successful login
 +  def successful_login(user)
 +    session[:user] = user.id
 +
 +    session_expires_after 1.month if session[:remember_me]
 +
 +    if user.blocked_on_view
 +      redirect_to user.blocked_on_view, :referer => params[:referer]
 +    elsif session[:referer]
 +      redirect_to session[:referer]
 +    else
 +      redirect_to :controller => 'site', :action => 'index'
 +    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.
index 992ec9be1aa4790e90017b4c8e1927737612fe73,66d8826c2d4fcc0ed227a4208edecabb534b2704..83a4d39e4e8d659b2d604bd4c5bd39f6e6626ad5
@@@ -2,91 -2,37 +2,89 @@@
  
  <% if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"}) %>
  
 -<p><%= t 'user.new.no_auto_account_create' %>
 -</p>
 +<p><%= t 'user.new.no_auto_account_create' %></p>
  
 -<p><%= t 'user.new.contact_webmaster' %>
 -</p>
 +<p><%= t 'user.new.contact_webmaster' %></p>
  
  <% else %>
  
 -<p><%= t 'user.new.fill_form' %>
 -</p>
 +<p><%= t 'user.new.fill_form' %></p>
  
- <p><%= t 'user.new.license_agreement' %></p>
  <%= error_messages_for 'user' %>
  
- <% form_tag :action => 'save' do %>
+ <% form_tag :action => 'terms' do %>
 -<%= hidden_field_tag('referer', h(params[:referer])) unless params[:referer].nil? %>
 -<table id="signupForm">
 -  <tr><td class="fieldName"><%= t 'user.new.email address' %></td><td><%= text_field('user', 'email',{:size => 50, :maxlength => 255, :tabindex => 1}) %></td></tr>
 -  <tr><td class="fieldName"><%= t 'user.new.confirm email address' %></td><td><%= text_field('user', 'email_confirmation',{:size => 50, :maxlength => 255, :tabindex => 2}) %></td></tr>
 -  <tr><td></td><td><span class="minorNote"><%= t 'user.new.not displayed publicly' %></span></td></tr>
 -  <tr><td colspan="2">&nbsp;<!--vertical spacer--></td></tr>
 -  <tr><td class="fieldName"><%= t 'user.new.display name' %></td><td><%= text_field('user', 'display_name',{:size => 30, :maxlength => 255, :tabindex => 3}) %></td></tr>
 -  <tr><td></td><td><span class="minorNote"><%= t 'user.new.display name description' %></span></td></tr>
 -  <tr><td colspan="2">&nbsp;<!--vertical spacer--></td></tr>
 -  <tr><td class="fieldName"><%= t 'user.new.password' %></td><td><%= password_field('user', 'pass_crypt',{:size => 30, :maxlength => 255, :tabindex => 4}) %></td></tr>
 -  <tr><td class="fieldName"><%= t 'user.new.confirm password' %></td><td><%= password_field('user', 'pass_crypt_confirmation',{:size => 30, :maxlength => 255, :tabindex => 5}) %></td></tr>
 -  
 -  <tr><td colspan="2">&nbsp;<!--vertical spacer--></td></tr>
 -  <tr><td></td><td align="right"><input type="submit" value="<%= t'user.new.continue' %>" tabindex="6"></td></tr>
 -</table>
 +  <%= hidden_field_tag('referer', h(@referer)) unless @referer.nil? %>
 +
 +  <table id="signupForm">
 +    <tr>
 +      <td class="fieldName"><%= t 'user.new.email address' %></td>
 +      <td><%= text_field(:user, :email, { :size => 50, :maxlength => 255, :tabindex => 1, :value => params[:email] }) %></td>
 +    </tr>
 +    <tr>
 +      <td class="fieldName"><%= t 'user.new.confirm email address' %></td>
 +      <td><%= text_field(:user, :email_confirmation, { :size => 50, :maxlength => 255, :tabindex => 2, :value => params[:email] }) %></td>
 +    </tr>
 +    <tr>
 +      <td></td>
 +      <td><span class="minorNote"><%= t 'user.new.not displayed publicly' %></span></td>
 +    </tr>
 +
 +    <tr><td colspan="2">&nbsp;<!--vertical spacer--></td></tr>
 +
 +    <tr>
 +      <td class="fieldName"><%= t 'user.new.display name' %></td>
 +      <td><%= text_field(:user, :display_name, { :size => 30, :maxlength => 255, :tabindex => 3, :value => params[:nickname] }) %></td></tr>
 +    <tr>
 +      <td></td>
 +      <td><span class="minorNote"><%= t 'user.new.display name description' %></span></td>
 +    </tr>
 +
 +    <tr id="openid_spacer"><td colspan="2">&nbsp;<!--vertical spacer--></td></tr>
 +
 +    <tr id="openid_url">
 +      <td class="fieldName"><%= t 'user.new.openid', :logo => openid_logo %></td>
 +      <td><%= text_field(:user, :openid_url, { :size => 50, :maxlength => 255, :tabindex => 4, :value => params[:openid], :class => "openid_url" }) %></td>
 +    </tr>
 +
 +    <tr><td colspan="2">&nbsp;<!--vertical spacer--></td></tr>
 +
 +    <tr>
 +      <td class="fieldName"><%= t 'user.new.password' %></td>
 +      <td><%= password_field(:user, :pass_crypt, { :size => 30, :maxlength => 255, :tabindex => 5 }) %></td>
 +    </tr>
 +    <tr>
 +      <td class="fieldName"><%= t 'user.new.confirm password' %></td>
 +      <td><%= password_field(:user, :pass_crypt_confirmation, { :size => 30, :maxlength => 255, :tabindex => 6 }) %></td>
 +    </tr>
 +    <tr>
 +      <td></td>
 +      <td>
 +        <span id="openid_prompt" class="minorNote"><%= link_to_function(t('user.new.use openid', :logo => openid_logo)) { |page| page.hide 'openid_prompt'; page.show 'openid_spacer', 'openid_url', 'openid_note' } %></span>
 +        <span id="openid_note" class="minorNote"><%= t 'user.new.openid no password' %></span>
 +      </td>
 +    </tr>
 +
 +    <tr><td colspan="2" >&nbsp;<!--vertical spacer--></td></tr>
 +
 +    <tr>
 +      <td></td>
-       <td align="right"><%= submit_tag t('user.new.signup'), :tabindex => 6 %></td>
++      <td align="right"><%= submit_tag t('user.new.continue'), :tabindex => 6 %></td>
 +    </tr>
 +  </table>
  <% end %>
  
 +<%=
 +  update_page_tag do |page|
 +    if params[:openid] 
 +      page[:openid_prompt].hide
 +    else
 +      page[:openid_spacer].hide
 +      page[:openid_url].hide
 +      page[:openid_note].hide
 +    end
 +  end
 +%>
 +
  <%= javascript_include_tag 'https://ethnio.com/remotes/62786' %>
  
  <% end %>
index 0000000000000000000000000000000000000000,049e07ca7d0b71adca4671446946e7fda4ca65ca..ae801bc11b45163b2b5918df487dbefc241ef99b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,46 +1,47 @@@
+ <h1><%= t 'user.terms.heading' %></h1>
+ <p><%= t 'user.terms.press accept button' %></p>
+ <!-- legale is <%= @legale %> -->
+ <% form_tag :action => 'terms' do %>
+   <p>
+     <%= t 'user.terms.legale_select' %>
+     <% [['france', 'FR'], ['italy', 'IT'], ['rest_of_world', 'GB']].each do |name,legale| %>
+       <%=
+         radio_button_tag 'legale', legale, @legale == legale,
+           :onchange => remote_function(
+             :before => update_page do |page|
+               page.replace_html 'contributorTerms', image_tag('searching.gif')
+             end,
+             :url => {:legale => legale}
+           )
+       %>
+       <%= label_tag "legale_#{legale}", t('user.terms.legale_names.' + name) %>
+     <% end %>
+   </p>
+ <% end %>
+ <div id="contributorTerms">
+   <%= render :partial => "terms" %>
+ </div>
+ <% form_tag({:action => "save"}, { :id => "termsForm" }) do %>
+   <p>
+     <label for="confirm_pd_checkbox"><%= t 'user.terms.consider_pd' %></label>
+     <%= check_box('user', 'consider_pd') %>
+     <span class="minorNote">(<%= link_to(t('user.terms.consider_pd_why'), t('user.terms.consider_pd_why_url'), :target => :new)%>)</span>
+   </p>
+   <p>
+     <%= hidden_field_tag('referer', h(params[:referer])) unless params[:referer].nil? %>
+     <%= hidden_field('user', 'email') %>
+     <%= hidden_field('user', 'email_confirmation') %>
+     <%= hidden_field('user', 'display_name') %>
+     <%= hidden_field('user', 'pass_crypt') %>
+     <%= hidden_field('user', 'pass_crypt_confirmation') %>
++    <%= hidden_field('user', 'openid_url') %>
+     <div id="buttons">
+       <%= submit_tag(t('user.terms.decline'), :name => "decline", :id => "decline") %>
+       <%= submit_tag(t('user.terms.agree'), :name => "agree", :id => "agree") %>
+     </div>
+   </p>
+ <% end %>
diff --combined config/locales/en.yml
index 7e6592165d20b18448fb8a973d3ac7cfd631cfc5,5abae7222ec5b3617d17e3ab10790e243ffa3af3..cc2dc5e980639f254e745c72e1fd8d917378ac01
        create_account: "create an account"
        email or username: "Email Address or Username:"
        password: "Password:"
 +      openid: "{{logo}} OpenID:"
 +      username_heading: "Login with username and password:"
 +      openid_heading: "Login with OpenID:"
        remember: "Remember me:"
        lost password link: "Lost your password?"
        login_button: "Login"
        account not active: "Sorry, your account is not active yet.<br />Please click on the link in the account confirmation email to activate your account."
        account suspended: Sorry, your account has been suspended due to suspicious activity.<br />Please contact the <a href="mailto:webmaster@openstreetmap.org">webmaster</a> if you wish to discuss this.
        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 to be malformed"
 +      openid_logo_alt: "Log in with an OpenID"
 +      openid_providers:
 +        openid:
 +          title: Login with an OpenID URL
 +          alt: Login with an OpenID URL
 +        yahoo:
 +          title: Login with a Yahoo! OpenID
 +          alt: Login with a Yahoo! OpenID
 +        google:
 +          title: Login with a Google OpenID
 +          alt: Login with a Google OpenID
 +        myopenid:
 +          title: Login with a myOpenID OpenID
 +          alt: Login with a myOpenID OpenID
 +        wordpress:
 +          title: Login with a Wordpress.com OpenID
 +          alt: Login with a Wordpress.com OpenID
 +        myspace:
 +          title: Login with a MySpace OpenID
 +          alt: Login with a MySpace OpenID
      logout:
        title: "Logout"
        heading: "Logout from OpenStreetMap"
        no_auto_account_create: "Unfortunately we are not currently able to create an account for you automatically."
        contact_webmaster: 'Please contact the <a href="mailto:webmaster@openstreetmap.org">webmaster</a> to arrange for an account to be created - we will try and deal with the request as quickly as possible.'
        fill_form: "Fill in the form and we will send you a quick email to activate your account."
-       license_agreement: 'By creating an account, you agree that all data you submit to the Openstreetmap project is to be (non-exclusively) licensed under <a href="http://creativecommons.org/licenses/by-sa/2.0/">this Creative Commons license (by-sa)</a>.'
+       license_agreement: 'When you confirm your account you will need to agree to the <a href="http://www.osmfoundation.org/wiki/License/Contributor_Terms">contributor terms</a>.'
        email address: "Email Address:"
        confirm email address: "Confirm Email Address:"
        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:"
-       signup: Signup
 +      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: "User was successfully created. Check your email for a confirmation note, and you will be mapping in no time :-)<br /><br />Please note that you will not be able to login until you've received and confirmed your email address.<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:
+       heading: "Contributor terms"
+       press accept button: "Please read the agreement below and press the agree button to create your account."
+       consider_pd: "I consider my contributions to be in the Public Domain"
+       consider_pd_why: "what's this?"
+       consider_pd_why_url: http://wiki.openstreetmap.org/wiki/Why_would_I_want_my_contributions_to_be_public_domain
+       agree: Agree
+       declined: "http://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined"
+       decline: "Decline"
+       legale_select: "Please select your country of residence:"
+       legale_button: "Go"
+       legale_names:
+         france: "France"
+         italy: "Italy"
+         rest_of_world: "Rest of the world"
      no_such_user:
        title: "No such user"
        heading: "The user {{user}} does not exist"
        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."
index 7dfff209df19b5f8fea6192e04121e1b083b34d1,0000000000000000000000000000000000000000..7dfff209df19b5f8fea6192e04121e1b083b34d1
mode 100644,000000..100644
--- /dev/null
@@@ -1,30 -1,0 +1,30 @@@
 +class AddOpenIdAuthenticationTables < ActiveRecord::Migration
 +  def self.up
 +    create_table :open_id_authentication_associations, :force => true do |t|
 +      t.integer :issued, :lifetime
 +      t.string :handle, :assoc_type
 +      t.binary :server_url, :secret
 +    end
 +
 +    create_table :open_id_authentication_nonces, :force => true do |t|
 +      t.integer :timestamp, :null => false
 +      t.string :server_url, :null => true
 +      t.string :salt, :null => false
 +    end
 +    
 +    add_column :users, :openid_url, :string 
 +
 +    add_index :users, [:openid_url], :name => "user_openid_unique_idx", :unique => true
 +    add_index :open_id_authentication_associations, [:server_url], :name => "open_id_associations_server_url_idx"
 +    add_index :open_id_authentication_nonces, [:timestamp], :name => "open_id_nonces_timestamp_idx"
 +  end
 +
 +  def self.down
 +    remove_index :users, :name => "user_openid_unique_idx"
 +    remove_index :open_id_authentication_associations, :name => "open_id_associations_server_url_idx"
 +    remove_index :open_id_authentication_nonces, :name => "open_id_nonces_timestamp_idx"
 +    remove_column :users, :openid_url
 +    drop_table :open_id_authentication_associations
 +    drop_table :open_id_authentication_nonces
 +  end
 +end
index 0282e47f315f99762d07c8218b3096fb286e2fa6,2590c2d5f655a3d456bb320c7447643884e9b83a..9d4ecb44515aef0e4c28347ed856fe2a49c58306
@@@ -583,37 -583,47 +583,78 @@@ hr 
    margin-top: 10px;
  }
  
 +/* Rules for the login form */
 +
 +.loginBox {
 +  float: left;
 +  border-style: solid;
 +  border-width: 1px;
 +  padding-left: 10px;
 +  padding-right: 10px;
 +  padding-bottom: 10px;
 +}
 +
 +.loginBox table {
 +  width: 100%;
 +}
 +
 +.loginBox img {
 +  border: 0;
 +}
 +
 +.loginBox #openid_buttons img {
 +  vertical-align: middle;
 +}
 +
 +.loginBox input[type="submit"] {
 +  float: right;
 +}
 +
 +#openid_buttons {
 +  margin-bottom: 20px;
 +}
 +
+ /* Rules for the account confirmation page */
+ div#contributorTerms {
+   border: 1px solid black;
+   padding: 4px;
+   overflow: auto;
+   width: 80%;
+   height: 60%;
+ }
+ div#contributorTerms p#first {
+   margin-top: 0px;
+ }
+ div#contributorTerms p#last {
+   margin-bottom: 0px;
+ }
+ div#contributorTerms ol {
+   margin-bottom: 0px;
+ }
+ div#contributorTerms img {
+   display: block;
+   margin-left: auto;
+   margin-right: auto;
+   margin-top: 10%;
+ }
+ form#termsForm {
+   width: 80%;
+ }
+ form#termsForm div#buttons {
+   float: right;
+ }
+ form#termsForm input#agree {
+   margin-left: 50px;
+ }
  /* Rules for the account settings page */
  
  #accountForm td {
@@@ -749,11 -759,6 +790,11 @@@ input[type="submit"] 
    border: 1px solid black;
  }
  
 +input.openid_url { 
 +  background: url('../images/openid_input.png') repeat-y left;
 +  padding-left: 16px;
 +}
 +
  /* Rules for user images */
  
  img.user_image {
@@@ -796,10 -801,3 +837,10 @@@ abbr.geo 
  .table1 { 
    background: #fff;
  }
 +
 +/* Rules for OpenID logo */
 +
 +.openid_logo {
 +  vertical-align: text-bottom;
 +  border: 0;
 +}