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 |