From 896e64b759aee595766969799bb2169e65a46cd6 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Wed, 11 Feb 2009 19:07:07 +0000 Subject: [PATCH] Added the ability to login via OpenID. * Refactored AccountController#login to use either password or openid based authentication * Extracted AccountController#successful_authentication to setup a user's session cookies and redirect * Implemented the start of AccountController#open_id_authentication which will check with the OpenID server and perform authentication. * Added text field for the OpenID url to /login * Added identity_url for OpenID to the user forms. * Added option to login with OpenID to the register form. * Added a root url route, which is used by the OpenID plugin #699 git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2442 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/account_controller.rb | 75 ++++++++++++++++++++------ app/views/account/login.rhtml | 4 ++ app/views/account/register.rhtml | 5 +- app/views/my/account.rhtml | 1 + app/views/users/_form.rhtml | 1 + config/routes.rb | 2 + lang/en.yml | 2 + public/images/openid-bg.gif | Bin 0 -> 328 bytes public/stylesheets/application.css | 2 + 9 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 public/images/openid-bg.gif diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index fe44740a4..2e280dac9 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -46,24 +46,10 @@ class AccountController < ApplicationController self.logged_user = nil else # Authenticate user - user = User.try_to_login(params[:username], params[:password]) - if user.nil? - # Invalid credentials - flash.now[:error] = l(:notice_account_invalid_creditentials) - elsif user.new_record? - # Onthefly creation failed, display the registration form to fill/fix attributes - @user = user - session[:auth_source_registration] = {:login => user.login, :auth_source_id => user.auth_source_id } - render :action => 'register' + unless using_open_id? + password_authentication else - # Valid user - self.logged_user = user - # generate a key and set cookie if autologin - if params[:autologin] && Setting.autologin? - token = Token.create(:user => user, :action => 'autologin') - cookies[:autologin] = { :value => token.value, :expires => 1.year.from_now } - end - redirect_back_or_default :controller => 'my', :action => 'page' + open_id_authenticate(params[:openid_url]) end end end @@ -191,4 +177,59 @@ private session[:user_id] = nil end end + + def password_authentication + user = User.try_to_login(params[:username], params[:password]) + if user.nil? + # Invalid credentials + flash.now[:error] = l(:notice_account_invalid_creditentials) + elsif user.new_record? + # Onthefly creation failed, display the registration form to fill/fix attributes + @user = user + session[:auth_source_registration] = {:login => user.login, :auth_source_id => user.auth_source_id } + render :action => 'register' + else + # Valid user + successful_authentication(user) + end + end + + + def open_id_authenticate(openid_url) + user = nil + authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => signin_url) do |result, identity_url, registration| + if result.successful? + user = User.find_or_initialize_by_identity_url(identity_url) + if user.new_record? + # Create on the fly + # TODO: name + user.login = registration['nickname'] + user.mail = registration['email'] + user.save + end + + user.reload + if user.new_record? + # Onthefly creation failed, display the registration form to fill/fix attributes + @user = user + session[:auth_source_registration] = {:login => user.login, :identity_url => identity_url } + render :action => 'register' + else + successful_authentication(user) + end + end + end + end + + def successful_authentication(user) + # Valid user + self.logged_user = user + # generate a key and set cookie if autologin + if params[:autologin] && Setting.autologin? + token = Token.create(:user => user, :action => 'autologin') + cookies[:autologin] = { :value => token.value, :expires => 1.year.from_now } + end + redirect_back_or_default :controller => 'my', :action => 'page' + end + end diff --git a/app/views/account/login.rhtml b/app/views/account/login.rhtml index d8c1f313f..d7a27821e 100644 --- a/app/views/account/login.rhtml +++ b/app/views/account/login.rhtml @@ -10,6 +10,10 @@ <%= password_field_tag 'password', nil, :size => 40 %> + + + <%= text_field_tag "openid_url" %> + diff --git a/app/views/account/register.rhtml b/app/views/account/register.rhtml index 45719f055..71367e9b9 100644 --- a/app/views/account/register.rhtml +++ b/app/views/account/register.rhtml @@ -1,4 +1,4 @@ -

<%=l(:label_register)%>

+

<%=l(:label_register)%> <%=link_to l(:label_login_with_open_id_option), signin_url %>

<% form_tag({:action => 'register'}, :class => "tabular") do %> <%= error_messages_for 'user' %> @@ -29,6 +29,9 @@

<%= select("user", "language", lang_options_for_select) %>

+

+<%= text_field 'user', 'identity_url' %>

+ <% @user.custom_field_values.select {|v| v.editable? || v.required?}.each do |value| %>

<%= custom_field_tag_with_label :user, value %>

<% end %> diff --git a/app/views/my/account.rhtml b/app/views/my/account.rhtml index ef5b222e4..2fa91afb4 100644 --- a/app/views/my/account.rhtml +++ b/app/views/my/account.rhtml @@ -15,6 +15,7 @@

<%= f.text_field :lastname, :required => true %>

<%= f.text_field :mail, :required => true %>

<%= f.select :language, lang_options_for_select %>

+

<%= f.text_field :identity_url %>

<% @user.custom_field_values.select(&:editable?).each do |value| %>

<%= custom_field_tag_with_label :user, value %>

diff --git a/app/views/users/_form.rhtml b/app/views/users/_form.rhtml index 799ebde47..1579ea53b 100644 --- a/app/views/users/_form.rhtml +++ b/app/views/users/_form.rhtml @@ -7,6 +7,7 @@

<%= f.text_field :lastname, :required => true %>

<%= f.text_field :mail, :required => true %>

<%= f.select :language, lang_options_for_select %>

+

<%= f.text_field :identity_url %>

<% @user.custom_field_values.each do |value| %>

<%= custom_field_tag_with_label :user, value %>

diff --git a/config/routes.rb b/config/routes.rb index 475d447be..d20bc3c9f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -255,4 +255,6 @@ ActionController::Routing::Routes.draw do |map| # Install the default route as the lowest priority. map.connect ':controller/:action/:id' map.connect 'robots.txt', :controller => 'welcome', :action => 'robots' + # Used for OpenID + map.root :controller => 'account', :action => 'login' end diff --git a/lang/en.yml b/lang/en.yml index 246bfb13e..a75a52990 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -147,6 +147,7 @@ field_mail_notification: Email notifications field_admin: Administrator field_last_login_on: Last connection field_language: Language +field_identity_url: OpenID URL field_effective_date: Date field_password: Password field_new_password: New password @@ -332,6 +333,7 @@ label_information: Information label_information_plural: Information label_please_login: Please log in label_register: Register +label_login_with_open_id_option: or login with OpenID label_password_lost: Lost password label_home: Home label_my_page: My page diff --git a/public/images/openid-bg.gif b/public/images/openid-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2d8377db023a3915cc9e8c2f1f5c7462622f0a1 GIT binary patch literal 328 zcmZ?wbhEHb6krfwxXQrr>({UQ_wR4qxN*;(J#*&FS-N!TvSrKGuV4S?%F;i7{_Nbj z^V6qK`}XadJ9qBs)2Dx~3p;V*#MZ4_j~qF&aN)v#|Nb2~aNyvg9 ztXT2$=g%EGcI@80`{m1*Z{NOs{rdIFl`EeF4W-ruOthu2f ztl_Mdp@*QzZPDcui{^-N`o3xq@(UMrZh5FF-w`Y#$*8QNq^Zf+5a!Y$(d{Fk$;RMZ d?jf!z+?DC8mZr!$-G@O{mX$wbm9ry*H2@d`j5z=R literal 0 HcmV?d00001 diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index 02c4a8b1b..653ae152f 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -69,6 +69,8 @@ html>body #content { min-height: 600px; } #login-form table td {padding: 6px;} #login-form label {font-weight: bold;} +input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; } + .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; } /***** Links *****/