diff --git a/app/models/auth_source_ldap.rb b/app/models/auth_source_ldap.rb index d009ae33..1e2bf243 100644 --- a/app/models/auth_source_ldap.rb +++ b/app/models/auth_source_ldap.rb @@ -101,10 +101,17 @@ class AuthSourceLdap < AuthSource ldap_con = initialize_ldap_con(self.account, self.account_password) login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) - attrs = {} + custom_ldap_filter = custom_filter_to_ldap - ldap_con.search( :base => self.base_dn, - :filter => object_filter & login_filter, + if custom_ldap_filter.present? + search_filters = object_filter & login_filter & custom_ldap_filter + else + search_filters = object_filter & login_filter + end + attrs = {} + + ldap_con.search( :base => self.base_dn, + :filter => search_filters, :attributes=> search_attributes) do |entry| if onthefly_register? @@ -119,6 +126,17 @@ class AuthSourceLdap < AuthSource attrs end + def custom_filter_to_ldap + return nil unless custom_filter.present? + + begin + return Net::LDAP::Filter.construct(custom_filter) + rescue Net::LDAP::LdapError # Filter syntax error + logger.debug "LDAP custom filter syntax error for: #{custom_filter}" if logger && logger.debug? + return nil + end + end + def self.get_attr(entry, attr_name) if !attr_name.blank? entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name] diff --git a/app/views/ldap_auth_sources/_form.rhtml b/app/views/ldap_auth_sources/_form.rhtml index 9ffffafc..ef0fd5b1 100644 --- a/app/views/ldap_auth_sources/_form.rhtml +++ b/app/views/ldap_auth_sources/_form.rhtml @@ -25,6 +25,9 @@

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

+ +

+<%= text_field 'auth_source', 'custom_filter', :size => 60 %>

<%=l(:label_attribute_plural)%> diff --git a/config/locales/en.yml b/config/locales/en.yml index 8560fc8f..c89a1fa3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -307,6 +307,7 @@ en: field_text: Text field field_visible: Visible field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text" + field_custom_ldap_filter: Custom LDAP filter setting_app_title: Application title setting_app_subtitle: Application subtitle diff --git a/db/migrate/20100217010520_add_custom_filter_to_auth_sources.rb b/db/migrate/20100217010520_add_custom_filter_to_auth_sources.rb new file mode 100644 index 00000000..8543c297 --- /dev/null +++ b/db/migrate/20100217010520_add_custom_filter_to_auth_sources.rb @@ -0,0 +1,9 @@ +class AddCustomFilterToAuthSources < ActiveRecord::Migration + def self.up + add_column :auth_sources, :custom_filter, :string + end + + def self.down + remove_column :auth_sources, :custom_filter + end +end diff --git a/test/unit/auth_source_ldap_test.rb b/test/unit/auth_source_ldap_test.rb index b383b906..9fcdace9 100644 --- a/test/unit/auth_source_ldap_test.rb +++ b/test/unit/auth_source_ldap_test.rb @@ -69,6 +69,32 @@ class AuthSourceLdapTest < ActiveSupport::TestCase end end + context "using a valid custom filter" do + setup do + @auth.update_attributes(:custom_filter => "(& (homeDirectory=*) (sn=O*))") + end + + should "find a user who authenticates and matches the custom filter" do + assert_not_nil @auth.authenticate('example1', '123456') + end + + should "be nil for users who don't match the custom filter" do + assert_nil @auth.authenticate('edavis', '123456') + end + end + + context "using an invalid custom filter" do + setup do + # missing )) at the end + @auth.update_attributes(:custom_filter => "(& (homeDirectory=*) (sn=O*") + end + + should "skip the custom filter" do + assert_not_nil @auth.authenticate('example1', '123456') + assert_not_nil @auth.authenticate('edavis', '123456') + end + end + end else puts '(Test LDAP server not configured)'