Index: app/helpers/auth_sources_helper.rb =================================================================== --- app/helpers/auth_sources_helper.rb (revision 10088) +++ app/helpers/auth_sources_helper.rb (working copy) @@ -21,4 +21,11 @@ def auth_source_partial_name(auth_source) "form_#{auth_source.class.name.underscore}" end + + module Encryption + # Return an array of password encryptions + def self.encryptiontypes + ["MD5","SSHA","CLEAR"] + end + end end Index: app/models/auth_source_ldap.rb =================================================================== --- app/models/auth_source_ldap.rb (revision 10088) +++ app/models/auth_source_ldap.rb (working copy) @@ -18,6 +18,8 @@ require 'iconv' require 'net/ldap' require 'net/ldap/dn' +require 'digest' +require 'base64' class AuthSourceLdap < AuthSource validates_presence_of :host, :port, :attr_login @@ -66,6 +68,57 @@ "LDAP" end + def allow_password_changes? + return self.enabled_passwd + end + + def encode_password(clear_password) + chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a + salt = '' + 10.times { |i| salt << chars[rand(chars.size-1)] } + + if self.password_encryption == "MD5" + logger.debug "Encode as md5" + return "{MD5}"+Base64.encode64(Digest::MD5.digest(clear_password)).chomp! + end + if self.password_encryption == "SSHA" + logger.debug "Encode as ssha" + return "{SSHA}"+Base64.encode64(Digest::SHA1.digest(clear_password+salt)+salt).chomp! + end + + if self.password_encryption == "CLEAR" + logger.debug "Encode as cleartype" + return clear_password + end + end + + # change password + def change_password(login,password,newPassword) + begin + attrs = get_user_dn(login, password) + if attrs + if self.account.blank? || self.account_password.blank? + logger.debug "Binding with user account" + ldap_con = initialize_ldap_con(attrs[:dn], password) + else + logger.debug "Binding with administrator account" + ldap_con = initialize_ldap_con(self.account, self.account_password) + end + + ops = [ + [:delete, :userPassword, password], + [:add, :userPassword, newPassword] + ] + return ldap_con.modify :dn => attrs[:dn], :operations => ops + # This is another password change method, probably more common + #return ldap_con.replace_attribute attrs[:dn], :userPassword, encode_password(newPassword) + end + rescue + return false + end + return false + end + private def ldap_filter Index: app/models/user.rb =================================================================== --- app/models/user.rb (revision 10088) +++ app/models/user.rb (working copy) @@ -594,6 +594,19 @@ end end + def isExternal? + return auth_source_id.present? + end + + def changeExternalPassword(password,newPassword,newPasswordConfirm) + return false if newPassword == "" || newPassword.length < 4 + return false if newPassword != newPasswordConfirm + if (self.isExternal?) + return self.auth_source.change_password(self.login,password,newPassword) + end + return false + end + protected def validate_password_length Index: app/controllers/my_controller.rb =================================================================== --- app/controllers/my_controller.rb (revision 10088) +++ app/controllers/my_controller.rb (working copy) @@ -93,10 +93,19 @@ end if request.post? if @user.check_password?(params[:password]) - @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] - if @user.save - flash[:notice] = l(:notice_account_password_updated) - redirect_to :action => 'account' + if @user.isExternal? + if @user.changeExternalPassword(params[:password],params[:new_password], params[:new_password_confirmation]) + flash[:notice] = l(:notice_account_password_updated) + redirect_to :action => 'account' + else + flash[:error] = l(:notice_external_password_error) + end + else + @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] + if @user.save + flash[:notice] = l(:notice_account_password_updated) + redirect_to :action => 'account' + end end else flash[:error] = l(:notice_account_wrong_password) Index: app/views/auth_sources/_form_auth_source_ldap.html.erb =================================================================== --- app/views/auth_sources/_form_auth_source_ldap.html.erb (revision 10088) +++ app/views/auth_sources/_form_auth_source_ldap.html.erb (working copy) @@ -28,6 +28,9 @@

<%= check_box 'auth_source', 'onthefly_register' %>

+ +

+<%= check_box 'auth_source', 'enabled_passwd' %>

<%=l(:label_attribute_plural)%> @@ -42,6 +45,10 @@

<%= text_field 'auth_source', 'attr_mail', :size => 20 %>

+ +

+<%= select 'auth_source', 'password_encryption', AuthSourcesHelper::Encryption.encryptiontypes %> +

Index: config/locales/en.yml =================================================================== --- config/locales/en.yml (revision 10088) +++ config/locales/en.yml (working copy) @@ -140,6 +140,7 @@ general_pdf_encoding: UTF-8 general_first_day_of_week: '7' + notice_external_password_error: Error changing external password. notice_account_updated: Account was successfully updated. notice_account_invalid_creditentials: Invalid user or password notice_account_password_updated: Password was successfully updated. @@ -275,6 +276,8 @@ field_attr_lastname: Lastname attribute field_attr_mail: Email attribute field_onthefly: On-the-fly user creation + field_password_encryption: Encryption + field_enabled_passwd: Enabled password changing field_start_date: Start date field_done_ratio: "% Done" field_auth_source: Authentication mode