##// END OF EJS Templates
Improved on-the-fly account creation. If some attributes are missing (eg. not present in the LDAP) or are invalid, the registration form is displayed so that the user is able to fill or fix these attributes....
Jean-Philippe Lang -
r1661:eb1d969237a9
parent child
Show More
@@ -44,7 +44,16 class AccountController < ApplicationController
44 44 else
45 45 # Authenticate user
46 46 user = User.try_to_login(params[:username], params[:password])
47 if user
47 if user.nil?
48 # Invalid credentials
49 flash.now[:error] = l(:notice_account_invalid_creditentials)
50 elsif user.new_record?
51 # Onthefly creation failed, display the registration form to fill/fix attributes
52 @user = user
53 session[:auth_source_registration] = {:login => user.login, :auth_source_id => user.auth_source_id }
54 render :action => 'register'
55 else
56 # Valid user
48 57 self.logged_user = user
49 58 # generate a key and set cookie if autologin
50 59 if params[:autologin] && Setting.autologin?
@@ -52,12 +61,8 class AccountController < ApplicationController
52 61 cookies[:autologin] = { :value => token.value, :expires => 1.year.from_now }
53 62 end
54 63 redirect_back_or_default :controller => 'my', :action => 'page'
55 else
56 flash.now[:error] = l(:notice_account_invalid_creditentials)
57 64 end
58 65 end
59 rescue User::OnTheFlyCreationFailure
60 flash.now[:error] = 'Redmine could not retrieve the required information from the LDAP to create your account. Please, contact your Redmine administrator.'
61 66 end
62 67
63 68 # Log out current user and redirect to welcome page
@@ -107,14 +112,26 class AccountController < ApplicationController
107 112
108 113 # User self-registration
109 114 def register
110 redirect_to(home_url) && return unless Setting.self_registration?
115 redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
111 116 if request.get?
117 session[:auth_source_registration] = nil
112 118 @user = User.new(:language => Setting.default_language)
113 119 else
114 120 @user = User.new(params[:user])
115 121 @user.admin = false
116 @user.login = params[:user][:login]
117 122 @user.status = User::STATUS_REGISTERED
123 if session[:auth_source_registration]
124 @user.status = User::STATUS_ACTIVE
125 @user.login = session[:auth_source_registration][:login]
126 @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
127 if @user.save
128 session[:auth_source_registration] = nil
129 self.logged_user = @user
130 flash[:notice] = l(:notice_account_activated)
131 redirect_to :controller => 'my', :action => 'account'
132 end
133 else
134 @user.login = params[:user][:login]
118 135 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
119 136 case Setting.self_registration
120 137 when '1'
@@ -144,6 +161,7 class AccountController < ApplicationController
144 161 end
145 162 end
146 163 end
164 end
147 165
148 166 # Token based account activation
149 167 def activate
@@ -20,10 +20,7 class AuthSource < ActiveRecord::Base
20 20
21 21 validates_presence_of :name
22 22 validates_uniqueness_of :name
23 validates_length_of :name, :host, :maximum => 60
24 validates_length_of :account_password, :maximum => 60, :allow_nil => true
25 validates_length_of :account, :base_dn, :maximum => 255
26 validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30
23 validates_length_of :name, :maximum => 60
27 24
28 25 def authenticate(login, password)
29 26 end
@@ -20,7 +20,10 require 'iconv'
20 20
21 21 class AuthSourceLdap < AuthSource
22 22 validates_presence_of :host, :port, :attr_login
23 validates_presence_of :attr_firstname, :attr_lastname, :attr_mail, :if => Proc.new { |a| a.onthefly_register? }
23 validates_length_of :name, :host, :account_password, :maximum => 60, :allow_nil => true
24 validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
25 validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
26 validates_numericality_of :port, :only_integer => true
24 27
25 28 def after_initialize
26 29 self.port = 389 if self.port == 0
@@ -103,19 +103,16 class User < ActiveRecord::Base
103 103 # user is not yet registered, try to authenticate with available sources
104 104 attrs = AuthSource.authenticate(login, password)
105 105 if attrs
106 onthefly = new(*attrs)
107 onthefly.login = login
108 onthefly.language = Setting.default_language
109 if onthefly.save
110 user = find(:first, :conditions => ["login=?", login])
106 user = new(*attrs)
107 user.login = login
108 user.language = Setting.default_language
109 if user.save
110 user.reload
111 111 logger.info("User '#{user.login}' created from the LDAP") if logger
112 else
113 logger.error("User '#{onthefly.login}' found in LDAP but could not be created (#{onthefly.errors.full_messages.join(', ')})") if logger
114 raise OnTheFlyCreationFailure.new
115 112 end
116 113 end
117 114 end
118 user.update_attribute(:last_login_on, Time.now) if user
115 user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
119 116 user
120 117 rescue => text
121 118 raise text
@@ -5,6 +5,7
5 5
6 6 <div class="box">
7 7 <!--[form:user]-->
8 <% if @user.auth_source_id.nil? %>
8 9 <p><label for="user_login"><%=l(:field_login)%> <span class="required">*</span></label>
9 10 <%= text_field 'user', 'login', :size => 25 %></p>
10 11
@@ -14,6 +15,7
14 15
15 16 <p><label for="password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
16 17 <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
18 <% end %>
17 19
18 20 <p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label>
19 21 <%= text_field 'user', 'firstname' %></p>
@@ -22,14 +22,12
22 22
23 23 <p><label for="auth_source_base_dn"><%=l(:field_base_dn)%> <span class="required">*</span></label>
24 24 <%= text_field 'auth_source', 'base_dn', :size => 60 %></p>
25 </div>
26 25
27 <div class="box">
28 26 <p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label>
29 27 <%= check_box 'auth_source', 'onthefly_register' %></p>
28 </div>
30 29
31 <p>
32 <fieldset><legend><%=l(:label_attribute_plural)%></legend>
30 <fieldset class="box"><legend><%=l(:label_attribute_plural)%></legend>
33 31 <p><label for="auth_source_attr_login"><%=l(:field_login)%> <span class="required">*</span></label>
34 32 <%= text_field 'auth_source', 'attr_login', :size => 20 %></p>
35 33
@@ -42,7 +40,5
42 40 <p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label>
43 41 <%= text_field 'auth_source', 'attr_mail', :size => 20 %></p>
44 42 </fieldset>
45 </p>
46 </div>
47 43 <!--[eoform:auth_source]-->
48 44
@@ -17,6 +17,12
17 17
18 18 require "#{File.dirname(__FILE__)}/../test_helper"
19 19
20 begin
21 require 'mocha'
22 rescue
23 # Won't run some tests
24 end
25
20 26 class AccountTest < ActionController::IntegrationTest
21 27 fixtures :users
22 28
@@ -102,4 +108,46 class AccountTest < ActionController::IntegrationTest
102 108 assert_redirected_to 'account/login'
103 109 log_user('newuser', 'newpass')
104 110 end
111
112 if Object.const_defined?(:Mocha)
113
114 def test_onthefly_registration
115 # disable registration
116 Setting.self_registration = '0'
117 AuthSource.expects(:authenticate).returns([:login => 'foo', :firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com', :auth_source_id => 66])
118
119 post 'account/login', :username => 'foo', :password => 'bar'
120 assert_redirected_to 'my/page'
121
122 user = User.find_by_login('foo')
123 assert user.is_a?(User)
124 assert_equal 66, user.auth_source_id
125 assert user.hashed_password.blank?
126 end
127
128 def test_onthefly_registration_with_invalid_attributes
129 # disable registration
130 Setting.self_registration = '0'
131 AuthSource.expects(:authenticate).returns([:login => 'foo', :lastname => 'Smith', :auth_source_id => 66])
132
133 post 'account/login', :username => 'foo', :password => 'bar'
134 assert_response :success
135 assert_template 'account/register'
136 assert_tag :input, :attributes => { :name => 'user[firstname]', :value => '' }
137 assert_tag :input, :attributes => { :name => 'user[lastname]', :value => 'Smith' }
138 assert_no_tag :input, :attributes => { :name => 'user[login]' }
139 assert_no_tag :input, :attributes => { :name => 'user[password]' }
140
141 post 'account/register', :user => {:firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com'}
142 assert_redirected_to 'my/account'
143
144 user = User.find_by_login('foo')
145 assert user.is_a?(User)
146 assert_equal 66, user.auth_source_id
147 assert user.hashed_password.blank?
148 end
149
150 else
151 puts 'Mocha is missing. Skipping tests.'
152 end
105 153 end
General Comments 0
You need to be logged in to leave comments. Login now