Patch by Gregor Schmidt. git-svn-id: http://svn.redmine.org/redmine/trunk@17505 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/4.0.0
@@ -43,6 +43,7 @@ class AuthSource < ActiveRecord::Base | |||
'attr_mail', | |||
'onthefly_register', | |||
'tls', | |||
'verify_peer', | |||
'filter', | |||
'timeout' | |||
@@ -37,6 +37,14 @@ class AuthSourceLdap < AuthSource | |||
before_validation :strip_ldap_attributes | |||
safe_attributes 'ldap_mode' | |||
LDAP_MODES = [ | |||
:ldap, | |||
:ldaps_verify_none, | |||
:ldaps_verify_peer | |||
] | |||
def initialize(attributes=nil, *args) | |||
super | |||
self.port = 389 if self.port == 0 | |||
@@ -101,6 +109,31 @@ class AuthSourceLdap < AuthSource | |||
raise AuthSourceException.new(e.message) | |||
end | |||
def ldap_mode | |||
case | |||
when tls && verify_peer | |||
:ldaps_verify_peer | |||
when tls && !verify_peer | |||
:ldaps_verify_none | |||
else | |||
:ldap | |||
end | |||
end | |||
def ldap_mode=(ldap_mode) | |||
case ldap_mode.try(:to_sym) | |||
when :ldaps_verify_peer | |||
self.tls = true | |||
self.verify_peer = true | |||
when :ldaps_verify_none | |||
self.tls = true | |||
self.verify_peer = false | |||
else | |||
self.tls = false | |||
self.verify_peer = false | |||
end | |||
end | |||
private | |||
def with_timeout(&block) | |||
@@ -143,9 +176,18 @@ class AuthSourceLdap < AuthSource | |||
def initialize_ldap_con(ldap_user, ldap_password) | |||
options = { :host => self.host, | |||
:port => self.port, | |||
:encryption => (self.tls ? :simple_tls : nil) | |||
:port => self.port | |||
} | |||
if tls | |||
options[:encryption] = { | |||
:method => :simple_tls, | |||
# Always provide non-empty tls_options, to make sure, that all | |||
# OpenSSL::SSL::SSLContext::DEFAULT_PARAMS as well as the default cert | |||
# store are used. | |||
:tls_options => { :verify_mode => verify_peer? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE } | |||
} | |||
end | |||
options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank? | |||
Net::LDAP.new options | |||
end |
@@ -3,7 +3,11 @@ | |||
<div class="box tabular"> | |||
<p><%= f.text_field :name, :required => true %></p> | |||
<p><%= f.text_field :host, :required => true %></p> | |||
<p><%= f.text_field :port, :required => true, :size => 6 %> <%= f.check_box :tls, :no_label => true %> LDAPS</p> | |||
<p> | |||
<%= f.text_field :port, :required => true, :size => 6 %> | |||
<%= f.select :ldap_mode, AuthSourceLdap::LDAP_MODES.map { |m| [l("label_#{m}"), m] }, :no_label => true %> | |||
<em class="info ldaps_warning"><%= l("label_ldaps_warning") %></em> | |||
</p> | |||
<p><%= f.text_field :account %></p> | |||
<p><%= f.password_field :account_password, :label => :field_password, | |||
:name => 'dummy_password', |
@@ -608,7 +608,11 @@ de: | |||
label_latest_compatible_version: Letzte kompatible Version | |||
label_latest_revision: Aktuellste Revision | |||
label_latest_revision_plural: Aktuellste Revisionen | |||
label_ldap: LDAP | |||
label_ldap_authentication: LDAP-Authentifizierung | |||
label_ldaps_verify_none: LDAPS (ohne Zertifikatsprüfung) | |||
label_ldaps_verify_peer: LDAPS | |||
label_ldaps_warning: Es wird empfohlen, eine verschlüsselte LDAPS-Verbindung mit Zertifikatsprüfung zu verwenden, um Manipulationen während der Authentifizierung zu verhindern. | |||
label_less_or_equal: "<=" | |||
label_less_than_ago: vor weniger als | |||
label_link: Link |
@@ -892,7 +892,11 @@ en: | |||
label_general: General | |||
label_scm: SCM | |||
label_plugins: Plugins | |||
label_ldap: LDAP | |||
label_ldap_authentication: LDAP authentication | |||
label_ldaps_verify_none: LDAPS (without certificate check) | |||
label_ldaps_verify_peer: LDAPS | |||
label_ldaps_warning: It is recommended to use an encrypted LDAPS connection with certificate check to prevent any manipulation during the authentication process. | |||
label_downloads_abbr: D/L | |||
label_optional_description: Optional description | |||
label_add_another_file: Add another file |
@@ -0,0 +1,7 @@ | |||
class AddVerifyPeerToAuthSources < ActiveRecord::Migration[5.2] | |||
def change | |||
change_table :auth_sources do |t| | |||
t.boolean :verify_peer, default: true, null: false | |||
end | |||
end | |||
end |
@@ -857,6 +857,12 @@ function keepAnchorOnSignIn(form){ | |||
return true; | |||
} | |||
$(function ($) { | |||
$('#auth_source_ldap_mode').change(function () { | |||
$('.ldaps_warning').toggle($(this).val() != 'ldaps_verify_peer'); | |||
}).change(); | |||
}); | |||
$(document).ready(setupAjaxIndicator); | |||
$(document).ready(hideOnLoad); | |||
$(document).ready(addFormObserversForDoubleSubmit); |
@@ -40,6 +40,8 @@ class AuthSourceLdapTest < ActiveSupport::TestCase | |||
assert_nil auth_source.attr_mail | |||
assert_equal false, auth_source.onthefly_register | |||
assert_equal false, auth_source.tls | |||
assert_equal true, auth_source.verify_peer | |||
assert_equal :ldap, auth_source.ldap_mode | |||
assert_nil auth_source.filter | |||
assert_nil auth_source.timeout | |||
end | |||
@@ -77,6 +79,42 @@ class AuthSourceLdapTest < ActiveSupport::TestCase | |||
assert a.valid? | |||
end | |||
test 'ldap_mode setter sets tls and verify_peer' do | |||
a = AuthSourceLdap.new | |||
a.ldap_mode = 'ldaps_verify_peer' | |||
assert a.tls | |||
assert a.verify_peer | |||
a.ldap_mode = 'ldaps_verify_none' | |||
assert a.tls | |||
assert !a.verify_peer | |||
a.ldap_mode = 'ldap' | |||
assert !a.tls | |||
assert !a.verify_peer | |||
end | |||
test 'ldap_mode getter reads from tls and verify_peer' do | |||
a = AuthSourceLdap.new | |||
a.tls = true | |||
a.verify_peer = true | |||
assert_equal :ldaps_verify_peer, a.ldap_mode | |||
a.tls = true | |||
a.verify_peer = false | |||
assert_equal :ldaps_verify_none, a.ldap_mode | |||
a.tls = false | |||
a.verify_peer = false | |||
assert_equal :ldap, a.ldap_mode | |||
a.tls = false | |||
a.verify_peer = true | |||
assert_equal :ldap, a.ldap_mode | |||
end | |||
if ldap_configured? | |||
test '#authenticate with a valid LDAP user should return the user attributes' do | |||
auth = AuthSourceLdap.find(1) |