Patch #1568 ยป htauth_patch.patch
app/controllers/auth_sources_controller.rb (working copy) | ||
---|---|---|
34 | 34 |
end |
35 | 35 | |
36 | 36 |
def new |
37 |
@auth_source = AuthSourceLdap.new |
|
37 |
if params[:id]=='file' |
|
38 |
@auth_source = AuthSourceFile.new |
|
39 |
else |
|
40 |
@auth_source = AuthSourceLdap.new |
|
41 |
end |
|
38 | 42 |
end |
39 | 43 | |
40 | 44 |
def create |
41 |
@auth_source = AuthSourceLdap.new(params[:auth_source]) |
|
45 |
if params[:id]=='file' |
|
46 |
@auth_source = AuthSourceFile.new(params[:auth_source]) |
|
47 |
else |
|
48 |
@auth_source = AuthSourceLdap.new(params[:auth_source]) |
|
49 |
end |
|
42 | 50 |
if @auth_source.save |
43 | 51 |
flash[:notice] = l(:notice_successful_create) |
44 | 52 |
redirect_to :action => 'list' |
... | ... | |
47 | 55 |
end |
48 | 56 |
end |
49 | 57 | |
58 | ||
59 | ||
60 | ||
50 | 61 |
def edit |
51 | 62 |
@auth_source = AuthSource.find(params[:id]) |
52 | 63 |
end |
app/controllers/users_controller.rb (working copy) | ||
---|---|---|
56 | 56 |
@user = User.new(params[:user]) |
57 | 57 |
@user.admin = params[:user][:admin] || false |
58 | 58 |
@user.login = params[:user][:login] |
59 |
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id |
|
59 |
if @user.passwd? |
|
60 |
@user.password = params[:password] |
|
61 |
@user.password_confirmation = params[:password_confirmation] |
|
62 |
end |
|
60 | 63 |
if @user.save |
61 | 64 |
Mailer.deliver_account_information(@user, params[:password]) if params[:send_information] |
62 | 65 |
flash[:notice] = l(:notice_successful_create) |
app/models/auth_source.rb (working copy) | ||
---|---|---|
20 | 20 |
|
21 | 21 |
validates_presence_of :name |
22 | 22 |
validates_uniqueness_of :name |
23 |
validates_length_of :name, :host, :maximum => 60 |
|
24 |
validates_length_of :account_password, :maximum => 60, :allow_nil => true |
|
25 |
validates_length_of :account, :base_dn, :maximum => 255 |
|
26 |
validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30 |
|
23 |
validates_length_of :name, :maximum => 60 |
|
24 |
validates_length_of :account, :maximum => 255 |
|
27 | 25 | |
28 | 26 |
def authenticate(login, password) |
29 | 27 |
end |
28 | ||
29 |
def passwd? |
|
30 |
false |
|
31 |
end |
|
30 | 32 |
|
31 | 33 |
def test_connection |
32 | 34 |
end |
app/models/auth_source_file.rb (revision 0) | ||
---|---|---|
1 |
# redMine - project management software |
|
2 |
# Copyright (C) 2006 Jean-Philippe Lang |
|
3 |
# |
|
4 |
# This program is free software; you can redistribute it and/or |
|
5 |
# modify it under the terms of the GNU General Public License |
|
6 |
# as published by the Free Software Foundation; either version 2 |
|
7 |
# of the License, or (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU General Public License |
|
15 |
# along with this program; if not, write to the Free Software |
|
16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
17 | ||
18 |
require 'htauth' |
|
19 | ||
20 |
class AuthSourceFile < AuthSource |
|
21 | ||
22 |
validates_presence_of :account |
|
23 |
|
|
24 |
def authenticate(login, password) |
|
25 |
return nil if login.blank? || password.blank? |
|
26 |
HTAuth::PasswdFile.open(self.account) do |pf| |
|
27 |
dn = pf.fetch(login) |
|
28 |
if dn and dn.authenticated?(password) |
|
29 |
logger.debug "Authenticated #{login}: #{dn}" if logger && logger.debug? |
|
30 |
return true |
|
31 |
else |
|
32 |
return false |
|
33 |
end |
|
34 |
end |
|
35 |
end |
|
36 |
|
|
37 |
def passwd? |
|
38 |
true |
|
39 |
end |
|
40 | ||
41 |
def passwd(login,password) |
|
42 |
return false if login.blank? || password.blank? |
|
43 |
HTAuth::PasswdFile.open(self.account) do |pf| |
|
44 |
logger.debug "add_or_update #{login}" if logger && logger.debug? |
|
45 |
pf.add_or_update(login,password) |
|
46 |
return true |
|
47 |
end |
|
48 |
end |
|
49 | ||
50 |
# test the connection to the LDAP |
|
51 |
def test_connection |
|
52 |
con = HTAuth::PasswdFile.open(self.account) |
|
53 |
return con.is_a?(HTAuth::PasswdFile) |
|
54 |
end |
|
55 |
|
|
56 |
def auth_method_name |
|
57 |
"HTAUTH" |
|
58 |
end |
|
59 |
|
|
60 |
private |
|
61 |
end |
app/models/auth_source_ldap.rb (working copy) | ||
---|---|---|
21 | 21 |
class AuthSourceLdap < AuthSource |
22 | 22 |
validates_presence_of :host, :port, :attr_login |
23 | 23 |
validates_presence_of :attr_firstname, :attr_lastname, :attr_mail, :if => Proc.new { |a| a.onthefly_register? } |
24 |
validates_length_of :host, :maximum => 60 |
|
25 |
validates_length_of :account_password, :maximum => 60, :allow_nil => true |
|
26 |
validates_length_of :base_dn, :maximum => 255 |
|
27 |
validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30 |
|
24 | 28 |
|
25 | 29 |
def after_initialize |
26 | 30 |
self.port = 389 if self.port == 0 |
app/models/user.rb (working copy) | ||
---|---|---|
69 | 69 |
|
70 | 70 |
def before_save |
71 | 71 |
# update hashed_password if password was set |
72 |
self.hashed_password = User.hash_password(self.password) if self.password |
|
72 |
if self.password |
|
73 |
self.hashed_password = User.hash_password(self.password) |
|
74 |
if self.auth_source |
|
75 |
self.auth_source.passwd(self.login,self.password) |
|
76 |
end |
|
77 |
end |
|
73 | 78 |
end |
74 | 79 | |
75 | 80 |
def self.active |
... | ... | |
131 | 136 |
self.status == STATUS_ACTIVE |
132 | 137 |
end |
133 | 138 | |
139 |
def passwd? |
|
140 |
return true unless self.auth_source_id |
|
141 |
self.auth_source.passwd? |
|
142 |
end |
|
134 | 143 |
def registered? |
135 | 144 |
self.status == STATUS_REGISTERED |
136 | 145 |
end |
app/views/auth_sources/_file_form.rhtml (revision 0) | ||
---|---|---|
1 |
<%= error_messages_for 'auth_source' %> |
|
2 | ||
3 |
<div class="box"> |
|
4 |
<!--[form:auth_source]--> |
|
5 |
<p><label for="auth_source_name"><%=l(:field_name)%> <span class="required">*</span></label> |
|
6 |
<%= text_field 'auth_source', 'name' %></p> |
|
7 | ||
8 |
<p><label for="auth_source_filename"><%=l(:field_account)%></label> |
|
9 |
<%= text_field 'auth_source', 'account' %></p> |
|
10 | ||
11 |
</div> |
|
12 |
<!--[eoform:auth_source]--> |
|
13 |
app/views/auth_sources/list.rhtml (working copy) | ||
---|---|---|
1 | 1 |
<div class="contextual"> |
2 |
<%= link_to l(:label_auth_source_new), {:action => 'new'}, :class => 'icon icon-add' %> |
|
2 |
<%= link_to l(:label_auth_source_ldap_new), {:action => 'new'}, :class => 'icon icon-add' %> |
|
3 |
<%= link_to l(:label_auth_source_file_new), {:action => 'new',:id=>'file'}, :class => 'icon icon-add' %> |
|
3 | 4 |
</div> |
4 | 5 | |
5 | 6 |
<h2><%=l(:label_auth_source_plural)%></h2> |
app/views/auth_sources/new.rhtml (working copy) | ||
---|---|---|
1 | 1 |
<h2><%=l(:label_auth_source_new)%> (<%= @auth_source.auth_method_name %>)</h2> |
2 | 2 | |
3 |
<% form_tag({:action => 'create'}, :class => "tabular") do %> |
|
4 |
<%= render :partial => 'form' %> |
|
5 |
<%= submit_tag l(:button_create) %> |
|
6 |
<% end %> |
|
3 |
<% if @auth_source.is_a?(AuthSourceFile) %> |
|
4 | ||
5 |
<% form_tag({:action => 'create', :id=>'file'}, :class => "tabular") do %> |
|
6 |
<%= render :partial => 'file_form' %> |
|
7 |
<%= submit_tag l(:button_create) %> |
|
8 |
<% end %> |
|
9 | ||
10 |
<%else%> |
|
11 | ||
12 |
<% form_tag({:action => 'create'}, :class => "tabular") do %> |
|
13 |
<%= render :partial => 'form' %> |
|
14 |
<%= submit_tag l(:button_create) %> |
|
15 |
<% end %> |
|
16 | ||
17 |
<%end%> |
app/views/users/_form.rhtml (working copy) | ||
---|---|---|
18 | 18 |
<div class="box"> |
19 | 19 |
<h3><%=l(:label_authentication)%></h3> |
20 | 20 |
<% unless @auth_sources.empty? %> |
21 |
<p><%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {}, :onchange => "if (this.value=='') {Element.show('password_fields');} else {Element.hide('password_fields');}" %></p>
|
|
21 |
<p><%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {} %></p> |
|
22 | 22 |
<% end %> |
23 |
<div id="password_fields" style="<%= 'display:none;' if @user.auth_source %>"> |
|
23 | ||
24 |
<div id="password_fields" > |
|
24 | 25 |
<p><label for="password"><%=l(:field_password)%><span class="required"> *</span></label> |
25 | 26 |
<%= password_field_tag 'password', nil, :size => 25 %><br /> |
26 | 27 |
<em><%= l(:text_caracters_minimum, 4) %></em></p> |
lang/en.yml (working copy) | ||
---|---|---|
294 | 294 |
label_environment: Environment |
295 | 295 |
label_authentication: Authentication |
296 | 296 |
label_auth_source: Authentication mode |
297 |
label_auth_source_ldap_new: New Ldap authentication mode |
|
298 |
label_auth_source_file_new: New htpasswd authentication mode |
|
297 | 299 |
label_auth_source_new: New authentication mode |
298 | 300 |
label_auth_source_plural: Authentication modes |
299 | 301 |
label_subproject_plural: Subprojects |
test/unit/auth_source_file_test.rb (revision 0) | ||
---|---|---|
1 | ||
2 |
require File.dirname(__FILE__) + '/../test_helper' |
|
3 | ||
4 |
class AuthSourceFileTest < Test::Unit::TestCase |
|
5 |
fixtures :projects, :boards, :messages |
|
6 | ||
7 |
def setup |
|
8 |
system("htpasswd -c -b auth_file admin admin ") |
|
9 |
system("htpasswd -b auth_file test test ") |
|
10 |
@auth = AuthSourceFile.create(:account => 'auth_file') |
|
11 |
end |
|
12 | ||
13 |
def test_auth_name |
|
14 |
assert_equal "HTAUTH",@auth.auth_method_name |
|
15 |
end |
|
16 | ||
17 |
def test_connection |
|
18 |
assert @auth.test_connection |
|
19 |
end |
|
20 |
|
|
21 |
def test_auth_test_ok |
|
22 |
assert @auth.authenticate('test','test') |
|
23 |
end |
|
24 |
|
|
25 |
def test_auth_test_bad_password |
|
26 |
assert !@auth.authenticate('test','xxx') |
|
27 |
end |
|
28 | ||
29 |
def test_auth_test_bad_username |
|
30 |
assert !@auth.authenticate('testx','xxx') |
|
31 |
end |
|
32 |
|
|
33 |
def test_passwd_add_user |
|
34 |
assert !@auth.authenticate('testx','xxx') |
|
35 |
assert @auth.passwd('testx','xxx') |
|
36 |
assert @auth.authenticate('testx','xxx') |
|
37 |
end |
|
38 | ||
39 |
def test_passwd_update_user |
|
40 |
assert !@auth.authenticate('test','xxx') |
|
41 |
assert @auth.passwd('test','xxx') |
|
42 |
assert @auth.authenticate('test','xxx') |
|
43 |
end |
|
44 | ||
45 |
end |