Patch #5690 » ldappassword.patch
| app/controllers/my_controller.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 1 |
# Redmine - project management software
|
|
| 2 | 2 |
# Copyright (C) 2006-2009 Jean-Philippe Lang |
| 3 | 3 |
# |
| 4 | 4 |
# This program is free software; you can redistribute it and/or |
| ... | ... | |
| 84 | 84 |
end |
| 85 | 85 |
if request.post? |
| 86 | 86 |
if @user.check_password?(params[:password]) |
| 87 |
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] |
|
| 88 |
if @user.save |
|
| 89 |
flash[:notice] = l(:notice_account_password_updated) |
|
| 90 |
redirect_to :action => 'account' |
|
| 87 |
if @user.isExternal? |
|
| 88 |
if @user.changeExternalPassword(params[:password],params[:new_password], params[:new_password_confirmation]) |
|
| 89 |
flash[:notice] = l(:notice_account_password_updated) |
|
| 90 |
redirect_to :action => 'account' |
|
| 91 |
else |
|
| 92 |
flash[:error] = l(:notice_external_password_error) |
|
| 93 |
end |
|
| 94 |
else |
|
| 95 |
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] |
|
| 96 |
if @user.save |
|
| 97 |
flash[:notice] = l(:notice_account_password_updated) |
|
| 98 |
redirect_to :action => 'account' |
|
| 99 |
end |
|
| 91 | 100 |
end |
| 92 | 101 |
else |
| 93 | 102 |
flash[:error] = l(:notice_account_wrong_password) |
| app/helpers/auth_sources_helper.rb | ||
|---|---|---|
| 16 | 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 | 17 | |
| 18 | 18 |
module AuthSourcesHelper |
| 19 |
|
|
| 20 |
module Encryption |
|
| 21 |
# Return an array of password encryptions |
|
| 22 |
def self.encryptiontypes |
|
| 23 |
["MD5","SSHA","CLEAR"] |
|
| 24 |
end |
|
| 25 |
end |
|
| 19 | 26 |
end |
| app/models/auth_source_ldap.rb | ||
|---|---|---|
| 17 | 17 | |
| 18 | 18 |
require 'net/ldap' |
| 19 | 19 |
require 'iconv' |
| 20 |
require 'digest' |
|
| 21 |
require 'base64' |
|
| 20 | 22 | |
| 21 | 23 |
class AuthSourceLdap < AuthSource |
| 22 | 24 |
validates_presence_of :host, :port, :attr_login |
| ... | ... | |
| 24 | 26 |
validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true |
| 25 | 27 |
validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true |
| 26 | 28 |
validates_numericality_of :port, :only_integer => true |
| 27 |
|
|
| 28 | 29 |
before_validation :strip_ldap_attributes |
| 29 | 30 |
|
| 30 | 31 |
def after_initialize |
| 31 |
self.port = 389 if self.port == 0 |
|
| 32 |
self.port = 389 if self.port == 0
|
|
| 32 | 33 |
end |
| 33 | 34 |
|
| 34 | 35 |
def authenticate(login, password) |
| ... | ... | |
| 54 | 55 |
def auth_method_name |
| 55 | 56 |
"LDAP" |
| 56 | 57 |
end |
| 58 | ||
| 59 |
def allow_password_changes? |
|
| 60 |
return self.enabled_passwd |
|
| 61 |
end |
|
| 62 |
|
|
| 63 |
def encode_password(clear_password) |
|
| 64 |
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
|
| 65 |
salt = '' |
|
| 66 |
10.times { |i| salt << chars[rand(chars.size-1)] }
|
|
| 67 |
|
|
| 68 |
if self.password_encryption == "MD5" |
|
| 69 |
logger.debug "Encode as md5" |
|
| 70 |
return "{MD5}"+Base64.encode64(Digest::MD5.digest(clear_password)).chomp!
|
|
| 71 |
end |
|
| 72 |
if self.password_encryption == "SSHA" |
|
| 73 |
logger.debug "Encode as ssha" |
|
| 74 |
return "{SSHA}"+Base64.encode64(Digest::SHA1.digest(clear_password+salt)+salt).chomp!
|
|
| 75 |
end |
|
| 76 |
|
|
| 77 |
if self.password_encryption == "CLEAR" |
|
| 78 |
logger.debug "Encode as cleartype" |
|
| 79 |
return clear_password |
|
| 80 |
end |
|
| 81 |
end |
|
| 57 | 82 |
|
| 83 |
# change password |
|
| 84 |
def change_password(login,password,newPassword) |
|
| 85 |
begin |
|
| 86 |
attrs = get_user_dn(login) |
|
| 87 |
if attrs |
|
| 88 |
if self.account.blank? || self.account_password.blank? |
|
| 89 |
logger.debug "Binding with user account" |
|
| 90 |
ldap_con = initialize_ldap_con(attrs[:dn], password) |
|
| 91 |
else |
|
| 92 |
logger.debug "Binding with administrator account" |
|
| 93 |
ldap_con = initialize_ldap_con(self.account, self.account_password) |
|
| 94 |
end |
|
| 95 |
return ldap_con.replace_attribute attrs[:dn], :userPassword, encode_password(newPassword) |
|
| 96 |
end |
|
| 97 |
rescue |
|
| 98 |
return false |
|
| 99 |
end |
|
| 100 |
return false |
|
| 101 |
end |
|
| 102 |
|
|
| 58 | 103 |
private |
| 59 | 104 |
|
| 60 | 105 |
def strip_ldap_attributes |
| app/models/user.rb | ||
|---|---|---|
| 332 | 332 |
anonymous_user |
| 333 | 333 |
end |
| 334 | 334 |
|
| 335 |
def isExternal? |
|
| 336 |
return auth_source_id.present? |
|
| 337 |
end |
|
| 338 |
|
|
| 339 |
def changeExternalPassword(password,newPassword,newPasswordConfirm) |
|
| 340 |
return false if newPassword == "" || newPassword.length < 4 |
|
| 341 |
return false if newPassword != newPasswordConfirm |
|
| 342 |
if (self.isExternal?) |
|
| 343 |
return self.auth_source.change_password(self.login,password,newPassword) |
|
| 344 |
end |
|
| 345 |
return false |
|
| 346 |
end |
|
| 347 |
|
|
| 335 | 348 |
protected |
| 336 | 349 |
|
| 337 | 350 |
def validate |
| app/views/ldap_auth_sources/_form.rhtml | ||
|---|---|---|
| 25 | 25 | |
| 26 | 26 |
<p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label> |
| 27 | 27 |
<%= check_box 'auth_source', 'onthefly_register' %></p> |
| 28 |
<p><label for="auth_source_enabled_passwd"><%=l(:field_enabled_passwd)%></label> |
|
| 29 |
<%= check_box 'auth_source', 'enabled_passwd' %></p> |
|
| 28 | 30 |
</div> |
| 29 | 31 | |
| 30 | 32 |
<fieldset class="box"><legend><%=l(:label_attribute_plural)%></legend> |
| ... | ... | |
| 39 | 41 | |
| 40 | 42 |
<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label> |
| 41 | 43 |
<%= text_field 'auth_source', 'attr_mail', :size => 20 %></p> |
| 44 | ||
| 45 |
<p><label for="auth_source_password_encryption"><%=l(:field_password_encryption)%></label> |
|
| 46 |
<%= select 'auth_source', 'password_encryption', AuthSourcesHelper::Encryption.encryptiontypes %> |
|
| 47 |
</p> |
|
| 42 | 48 |
</fieldset> |
| 43 | 49 |
<!--[eoform:auth_source]--> |
| 44 | 50 | |
| config/locales/de.yml | ||
|---|---|---|
| 150 | 150 |
general_pdf_encoding: ISO-8859-1 |
| 151 | 151 |
general_first_day_of_week: '1' |
| 152 | 152 | |
| 153 |
notice_external_password_error: Externes Konto konnte nicht aktualisiert werden. |
|
| 153 | 154 |
notice_account_updated: Konto wurde erfolgreich aktualisiert. |
| 154 | 155 |
notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungültig. |
| 155 | 156 |
notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert. |
| 156 | 157 |
notice_account_wrong_password: Falsches Kennwort. |
| 157 | 158 |
notice_account_register_done: Konto wurde erfolgreich angelegt. |
| 158 | 159 |
notice_account_unknown_email: Unbekannter Benutzer. |
| 159 |
notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. Unmöglich, das Kennwort zu ändern.
|
|
| 160 |
notice_can_t_change_password: Kennwort ändern ist gesperrt für diese externe Authentifizierungs-Quelle.
|
|
| 160 | 161 |
notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wählen, wurde Ihnen geschickt. |
| 161 | 162 |
notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden. |
| 162 | 163 |
notice_successful_create: Erfolgreich angelegt |
| ... | ... | |
| 273 | 274 |
field_attr_lastname: Name-Attribut |
| 274 | 275 |
field_attr_mail: E-Mail-Attribut |
| 275 | 276 |
field_onthefly: On-the-fly-Benutzererstellung |
| 277 |
field_password_encryption: Verschlüsselungsart |
|
| 278 |
field_enabled_passwd: Password ändern erlauben |
|
| 276 | 279 |
field_start_date: Beginn |
| 277 | 280 |
field_done_ratio: % erledigt |
| 278 | 281 |
field_auth_source: Authentifizierungs-Modus |
| config/locales/en.yml | ||
|---|---|---|
| 127 | 127 |
general_pdf_encoding: ISO-8859-1 |
| 128 | 128 |
general_first_day_of_week: '7' |
| 129 | 129 |
|
| 130 |
notice_external_password_error: External password changing goes wrong |
|
| 130 | 131 |
notice_account_updated: Account was successfully updated. |
| 131 | 132 |
notice_account_invalid_creditentials: Invalid user or password |
| 132 | 133 |
notice_account_password_updated: Password was successfully updated. |
| ... | ... | |
| 253 | 254 |
field_attr_lastname: Lastname attribute |
| 254 | 255 |
field_attr_mail: Email attribute |
| 255 | 256 |
field_onthefly: On-the-fly user creation |
| 257 |
field_password_encryption: Encyrption |
|
| 258 |
field_enabled_passwd: Enabled password changing |
|
| 256 | 259 |
field_start_date: Start |
| 257 | 260 |
field_done_ratio: % Done |
| 258 | 261 |
field_auth_source: Authentication mode |
| db/migrate/20100609104539_ldap_password_change.rb | ||
|---|---|---|
| 1 |
class LdapPasswordChange < ActiveRecord::Migration |
|
| 2 |
def self.up |
|
| 3 |
add_column :auth_sources, :password_encryption, :string, :default => "MD5", :null => false |
|
| 4 |
add_column :auth_sources, :enabled_passwd, :boolean, :default => false, :null => false |
|
| 5 |
end |
|
| 6 | ||
| 7 |
def self.down |
|
| 8 |
remove_column :auth_sources, :password_encryption |
|
| 9 |
remove_column :auth_sources, :enabled_passwd |
|
| 10 |
end |
|
| 11 |
end |
|