else
# Authenticate user
user = User.try_to_login(params[:username], params[:password])
- if user
+ 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
self.logged_user = user
# generate a key and set cookie if autologin
if params[:autologin] && Setting.autologin?
cookies[:autologin] = { :value => token.value, :expires => 1.year.from_now }
end
redirect_back_or_default :controller => 'my', :action => 'page'
- else
- flash.now[:error] = l(:notice_account_invalid_creditentials)
end
end
- rescue User::OnTheFlyCreationFailure
- flash.now[:error] = 'Redmine could not retrieve the required information from the LDAP to create your account. Please, contact your Redmine administrator.'
end
# Log out current user and redirect to welcome page
# User self-registration
def register
- redirect_to(home_url) && return unless Setting.self_registration?
+ redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
if request.get?
+ session[:auth_source_registration] = nil
@user = User.new(:language => Setting.default_language)
else
@user = User.new(params[:user])
@user.admin = false
- @user.login = params[:user][:login]
@user.status = User::STATUS_REGISTERED
- @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
- case Setting.self_registration
- when '1'
- # Email activation
- token = Token.new(:user => @user, :action => "register")
- if @user.save and token.save
- Mailer.deliver_register(token)
- flash[:notice] = l(:notice_account_register_done)
- redirect_to :action => 'login'
- end
- when '3'
- # Automatic activation
+ if session[:auth_source_registration]
@user.status = User::STATUS_ACTIVE
+ @user.login = session[:auth_source_registration][:login]
+ @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
if @user.save
+ session[:auth_source_registration] = nil
self.logged_user = @user
flash[:notice] = l(:notice_account_activated)
redirect_to :controller => 'my', :action => 'account'
end
else
- # Manual activation by the administrator
- if @user.save
- # Sends an email to the administrators
- Mailer.deliver_account_activation_request(@user)
- flash[:notice] = l(:notice_account_pending)
- redirect_to :action => 'login'
+ @user.login = params[:user][:login]
+ @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
+ case Setting.self_registration
+ when '1'
+ # Email activation
+ token = Token.new(:user => @user, :action => "register")
+ if @user.save and token.save
+ Mailer.deliver_register(token)
+ flash[:notice] = l(:notice_account_register_done)
+ redirect_to :action => 'login'
+ end
+ when '3'
+ # Automatic activation
+ @user.status = User::STATUS_ACTIVE
+ if @user.save
+ self.logged_user = @user
+ flash[:notice] = l(:notice_account_activated)
+ redirect_to :controller => 'my', :action => 'account'
+ end
+ else
+ # Manual activation by the administrator
+ if @user.save
+ # Sends an email to the administrators
+ Mailer.deliver_account_activation_request(@user)
+ flash[:notice] = l(:notice_account_pending)
+ redirect_to :action => 'login'
+ end
end
end
end
validates_presence_of :name
validates_uniqueness_of :name
- validates_length_of :name, :host, :maximum => 60
- validates_length_of :account_password, :maximum => 60, :allow_nil => true
- validates_length_of :account, :base_dn, :maximum => 255
- validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30
+ validates_length_of :name, :maximum => 60
def authenticate(login, password)
end
class AuthSourceLdap < AuthSource
validates_presence_of :host, :port, :attr_login
- validates_presence_of :attr_firstname, :attr_lastname, :attr_mail, :if => Proc.new { |a| a.onthefly_register? }
+ validates_length_of :name, :host, :account_password, :maximum => 60, :allow_nil => true
+ validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
+ validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
+ validates_numericality_of :port, :only_integer => true
def after_initialize
self.port = 389 if self.port == 0
# user is not yet registered, try to authenticate with available sources
attrs = AuthSource.authenticate(login, password)
if attrs
- onthefly = new(*attrs)
- onthefly.login = login
- onthefly.language = Setting.default_language
- if onthefly.save
- user = find(:first, :conditions => ["login=?", login])
+ user = new(*attrs)
+ user.login = login
+ user.language = Setting.default_language
+ if user.save
+ user.reload
logger.info("User '#{user.login}' created from the LDAP") if logger
- else
- logger.error("User '#{onthefly.login}' found in LDAP but could not be created (#{onthefly.errors.full_messages.join(', ')})") if logger
- raise OnTheFlyCreationFailure.new
end
end
end
- user.update_attribute(:last_login_on, Time.now) if user
+ user.update_attribute(:last_login_on, Time.now) if user && !user.new_record?
user
rescue => text
raise text
<div class="box">
<!--[form:user]-->
+<% if @user.auth_source_id.nil? %>
<p><label for="user_login"><%=l(:field_login)%> <span class="required">*</span></label>
-<%= text_field 'user', 'login', :size => 25 %></p>
+<%= text_field 'user', 'login', :size => 25 %></p>
<p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
<%= password_field_tag 'password', nil, :size => 25 %><br />
<p><label for="password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
<%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
+<% end %>
<p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label>
<%= text_field 'user', 'firstname' %></p>
<p><label for="auth_source_base_dn"><%=l(:field_base_dn)%> <span class="required">*</span></label>
<%= text_field 'auth_source', 'base_dn', :size => 60 %></p>
-</div>
-<div class="box">
<p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label>
<%= check_box 'auth_source', 'onthefly_register' %></p>
+</div>
-<p>
-<fieldset><legend><%=l(:label_attribute_plural)%></legend>
+<fieldset class="box"><legend><%=l(:label_attribute_plural)%></legend>
<p><label for="auth_source_attr_login"><%=l(:field_login)%> <span class="required">*</span></label>
<%= text_field 'auth_source', 'attr_login', :size => 20 %></p>
<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label>
<%= text_field 'auth_source', 'attr_mail', :size => 20 %></p>
</fieldset>
-</p>
-</div>
<!--[eoform:auth_source]-->
require "#{File.dirname(__FILE__)}/../test_helper"
+begin
+ require 'mocha'
+rescue
+ # Won't run some tests
+end
+
class AccountTest < ActionController::IntegrationTest
fixtures :users
assert_redirected_to 'account/login'
log_user('newuser', 'newpass')
end
+
+ if Object.const_defined?(:Mocha)
+
+ def test_onthefly_registration
+ # disable registration
+ Setting.self_registration = '0'
+ AuthSource.expects(:authenticate).returns([:login => 'foo', :firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com', :auth_source_id => 66])
+
+ post 'account/login', :username => 'foo', :password => 'bar'
+ assert_redirected_to 'my/page'
+
+ user = User.find_by_login('foo')
+ assert user.is_a?(User)
+ assert_equal 66, user.auth_source_id
+ assert user.hashed_password.blank?
+ end
+
+ def test_onthefly_registration_with_invalid_attributes
+ # disable registration
+ Setting.self_registration = '0'
+ AuthSource.expects(:authenticate).returns([:login => 'foo', :lastname => 'Smith', :auth_source_id => 66])
+
+ post 'account/login', :username => 'foo', :password => 'bar'
+ assert_response :success
+ assert_template 'account/register'
+ assert_tag :input, :attributes => { :name => 'user[firstname]', :value => '' }
+ assert_tag :input, :attributes => { :name => 'user[lastname]', :value => 'Smith' }
+ assert_no_tag :input, :attributes => { :name => 'user[login]' }
+ assert_no_tag :input, :attributes => { :name => 'user[password]' }
+
+ post 'account/register', :user => {:firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com'}
+ assert_redirected_to 'my/account'
+
+ user = User.find_by_login('foo')
+ assert user.is_a?(User)
+ assert_equal 66, user.auth_source_id
+ assert user.hashed_password.blank?
+ end
+
+ else
+ puts 'Mocha is missing. Skipping tests.'
+ end
end