diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index f6867599..f637b49b 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -77,7 +77,7 @@ class MyController < ApplicationController # Manage user's password def password @user = User.current - if @user.auth_source_id + unless @user.change_password_allowed? flash[:error] = l(:notice_can_t_change_password) redirect_to :action => 'account' return diff --git a/app/models/auth_source.rb b/app/models/auth_source.rb index 537ed2d4..84f17b1b 100644 --- a/app/models/auth_source.rb +++ b/app/models/auth_source.rb @@ -32,6 +32,15 @@ class AuthSource < ActiveRecord::Base "Abstract" end + def allow_password_changes? + self.class.allow_password_changes? + end + + # Does this auth source backend allow password changes? + def self.allow_password_changes? + false + end + # Try to authenticate a user not yet registered against available sources def self.authenticate(login, password) AuthSource.find(:all, :conditions => ["onthefly_register=?", true]).each do |source| diff --git a/app/models/user.rb b/app/models/user.rb index 2dad3bb1..a38a0917 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -71,7 +71,7 @@ class User < Principal def before_save # update hashed_password if password was set - self.hashed_password = User.hash_password(self.password) if self.password + self.hashed_password = User.hash_password(self.password) if self.password && self.auth_source_id.blank? end def reload(*args) @@ -116,7 +116,7 @@ class User < Principal user.language = Setting.default_language if user.save user.reload - logger.info("User '#{user.login}' created from external auth source: #{user.auth_source.type} - #{user.auth_source.name}") if logger + logger.info("User '#{user.login}' created from external auth source: #{user.auth_source.type} - #{user.auth_source.name}") if logger && user.auth_source end end end @@ -161,7 +161,17 @@ class User < Principal end def check_password?(clear_password) - User.hash_password(clear_password) == self.hashed_password + if auth_source_id.present? + auth_source.authenticate(self.login, clear_password) + else + User.hash_password(clear_password) == self.hashed_password + end + end + + # Does the backend storage allow this user to change their password? + def change_password_allowed? + return true if auth_source_id.blank? + return auth_source.allow_password_changes? end # Generate and set a random password. Useful for automated user creation diff --git a/app/views/my/account.rhtml b/app/views/my/account.rhtml index 9bf45b33..befe6be5 100644 --- a/app/views/my/account.rhtml +++ b/app/views/my/account.rhtml @@ -1,5 +1,5 @@
-<%= link_to(l(:button_change_password), :action => 'password') unless @user.auth_source_id %> +<%= link_to(l(:button_change_password), :action => 'password') if @user.change_password_allowed? %> <%= call_hook(:view_my_account_contextual, :user => @user)%>

<%=l(:label_my_account)%>

diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index f6371650..77a9ee98 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -273,6 +273,32 @@ class UserTest < ActiveSupport::TestCase assert !u.password.blank? assert !u.password_confirmation.blank? end + + context "#change_password_allowed?" do + should "be allowed if no auth source is set" do + user = User.generate_with_protected! + assert user.change_password_allowed? + end + + should "delegate to the auth source" do + user = User.generate_with_protected! + + allowed_auth_source = AuthSource.generate! + def allowed_auth_source.allow_password_changes?; true; end + + denied_auth_source = AuthSource.generate! + def denied_auth_source.allow_password_changes?; false; end + + assert user.change_password_allowed? + + user.auth_source = allowed_auth_source + assert user.change_password_allowed?, "User not allowed to change password, though auth source does" + + user.auth_source = denied_auth_source + assert !user.change_password_allowed?, "User allowed to change password, though auth source does not" + end + + end if Object.const_defined?(:OpenID)