##// END OF EJS Templates
upgrade net-ldap gem to 0.12.0 (#17618)...
Toshi MARUYAMA -
r14402:7019f3416a5d
parent child
Show More
@@ -1,111 +1,111
1 1 source 'https://rubygems.org'
2 2
3 3 if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.5.0')
4 4 abort "Redmine requires Bundler 1.5.0 or higher (you're using #{Bundler::VERSION}).\nPlease update with 'gem update bundler'."
5 5 end
6 6
7 7 gem "rails", "4.2.4"
8 8 gem "jquery-rails", "~> 3.1.4"
9 9 gem "coderay", "~> 1.1.0"
10 10 gem "builder", ">= 3.0.4"
11 11 gem "request_store", "1.0.5"
12 12 gem "mime-types"
13 13 gem "protected_attributes"
14 14 gem "actionpack-action_caching"
15 15 gem "actionpack-xml_parser"
16 16 gem "roadie-rails"
17 17
18 18 # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
19 19 gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin, :jruby]
20 20 gem "rbpdf", "~> 1.18.6"
21 21
22 22 # Optional gem for LDAP authentication
23 23 group :ldap do
24 gem "net-ldap", "~> 0.10.1"
24 gem "net-ldap", "~> 0.12.0"
25 25 end
26 26
27 27 # Optional gem for OpenID authentication
28 28 group :openid do
29 29 gem "ruby-openid", "~> 2.3.0", :require => "openid"
30 30 gem "rack-openid"
31 31 end
32 32
33 33 platforms :mri, :mingw, :x64_mingw do
34 34 # Optional gem for exporting the gantt to a PNG file, not supported with jruby
35 35 group :rmagick do
36 36 gem "rmagick", ">= 2.14.0"
37 37 end
38 38
39 39 # Optional Markdown support, not for JRuby
40 40 group :markdown do
41 41 gem "redcarpet", "~> 3.3.2"
42 42 end
43 43 end
44 44
45 45 platforms :jruby do
46 46 # jruby-openssl is bundled with JRuby 1.7.0
47 47 gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
48 48 gem "activerecord-jdbc-adapter", "~> 1.3.2"
49 49 end
50 50
51 51 # Include database gems for the adapters found in the database
52 52 # configuration file
53 53 require 'erb'
54 54 require 'yaml'
55 55 database_file = File.join(File.dirname(__FILE__), "config/database.yml")
56 56 if File.exist?(database_file)
57 57 database_config = YAML::load(ERB.new(IO.read(database_file)).result)
58 58 adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
59 59 if adapters.any?
60 60 adapters.each do |adapter|
61 61 case adapter
62 62 when 'mysql2'
63 63 gem "mysql2", "~> 0.3.11", :platforms => [:mri, :mingw, :x64_mingw]
64 64 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
65 65 when 'mysql'
66 66 gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
67 67 when /postgresql/
68 68 gem "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw]
69 69 gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
70 70 when /sqlite3/
71 71 gem "sqlite3", :platforms => [:mri, :mingw, :x64_mingw]
72 72 gem "jdbc-sqlite3", ">= 3.8.10.1", :platforms => :jruby
73 73 gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
74 74 when /sqlserver/
75 75 gem "tiny_tds", "~> 0.6.2", :platforms => [:mri, :mingw, :x64_mingw]
76 76 gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw, :x64_mingw]
77 77 else
78 78 warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
79 79 end
80 80 end
81 81 else
82 82 warn("No adapter found in config/database.yml, please configure it first")
83 83 end
84 84 else
85 85 warn("Please configure your config/database.yml first")
86 86 end
87 87
88 88 group :development do
89 89 gem "rdoc", ">= 2.4.2"
90 90 gem "yard"
91 91 end
92 92
93 93 group :test do
94 94 gem "minitest"
95 95 gem "rails-dom-testing"
96 96 gem "mocha"
97 97 gem "simplecov", "~> 0.9.1", :require => false
98 98 # For running UI tests
99 99 gem "capybara"
100 100 gem "selenium-webdriver"
101 101 end
102 102
103 103 local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
104 104 if File.exists?(local_gemfile)
105 105 eval_gemfile local_gemfile
106 106 end
107 107
108 108 # Load plugins' Gemfiles
109 109 Dir.glob File.expand_path("../plugins/*/{Gemfile,PluginGemfile}", __FILE__) do |file|
110 110 eval_gemfile file
111 111 end
@@ -1,196 +1,196
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'net/ldap'
19 19 require 'net/ldap/dn'
20 20 require 'timeout'
21 21
22 22 class AuthSourceLdap < AuthSource
23 23 validates_presence_of :host, :port, :attr_login
24 24 validates_length_of :name, :host, :maximum => 60, :allow_nil => true
25 25 validates_length_of :account, :account_password, :base_dn, :maximum => 255, :allow_blank => true
26 26 validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
27 27 validates_numericality_of :port, :only_integer => true
28 28 validates_numericality_of :timeout, :only_integer => true, :allow_blank => true
29 29 validate :validate_filter
30 30
31 31 before_validation :strip_ldap_attributes
32 32
33 33 def initialize(attributes=nil, *args)
34 34 super
35 35 self.port = 389 if self.port == 0
36 36 end
37 37
38 38 def authenticate(login, password)
39 39 return nil if login.blank? || password.blank?
40 40
41 41 with_timeout do
42 42 attrs = get_user_dn(login, password)
43 43 if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
44 44 logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
45 45 return attrs.except(:dn)
46 46 end
47 47 end
48 48 rescue Net::LDAP::LdapError => e
49 49 raise AuthSourceException.new(e.message)
50 50 end
51 51
52 52 # test the connection to the LDAP
53 53 def test_connection
54 54 with_timeout do
55 55 ldap_con = initialize_ldap_con(self.account, self.account_password)
56 56 ldap_con.open { }
57 57 end
58 58 rescue Net::LDAP::LdapError => e
59 59 raise AuthSourceException.new(e.message)
60 60 end
61 61
62 62 def auth_method_name
63 63 "LDAP"
64 64 end
65 65
66 66 # Returns true if this source can be searched for users
67 67 def searchable?
68 68 !account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")}
69 69 end
70 70
71 71 # Searches the source for users and returns an array of results
72 72 def search(q)
73 73 q = q.to_s.strip
74 74 return [] unless searchable? && q.present?
75 75
76 76 results = []
77 77 search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q)
78 78 ldap_con = initialize_ldap_con(self.account, self.account_password)
79 79 ldap_con.search(:base => self.base_dn,
80 80 :filter => search_filter,
81 81 :attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail],
82 82 :size => 10) do |entry|
83 83 attrs = get_user_attributes_from_ldap_entry(entry)
84 84 attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login)
85 85 results << attrs
86 86 end
87 87 results
88 88 rescue Net::LDAP::LdapError => e
89 89 raise AuthSourceException.new(e.message)
90 90 end
91 91
92 92 private
93 93
94 94 def with_timeout(&block)
95 95 timeout = self.timeout
96 96 timeout = 20 unless timeout && timeout > 0
97 97 Timeout.timeout(timeout) do
98 98 return yield
99 99 end
100 100 rescue Timeout::Error => e
101 101 raise AuthSourceTimeoutException.new(e.message)
102 102 end
103 103
104 104 def ldap_filter
105 105 if filter.present?
106 106 Net::LDAP::Filter.construct(filter)
107 107 end
108 rescue Net::LDAP::LdapError
108 rescue Net::LDAP::LdapError, Net::LDAP::FilterSyntaxInvalidError
109 109 nil
110 110 end
111 111
112 112 def base_filter
113 113 filter = Net::LDAP::Filter.eq("objectClass", "*")
114 114 if f = ldap_filter
115 115 filter = filter & f
116 116 end
117 117 filter
118 118 end
119 119
120 120 def validate_filter
121 121 if filter.present? && ldap_filter.nil?
122 122 errors.add(:filter, :invalid)
123 123 end
124 124 end
125 125
126 126 def strip_ldap_attributes
127 127 [:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
128 128 write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
129 129 end
130 130 end
131 131
132 132 def initialize_ldap_con(ldap_user, ldap_password)
133 133 options = { :host => self.host,
134 134 :port => self.port,
135 135 :encryption => (self.tls ? :simple_tls : nil)
136 136 }
137 137 options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
138 138 Net::LDAP.new options
139 139 end
140 140
141 141 def get_user_attributes_from_ldap_entry(entry)
142 142 {
143 143 :dn => entry.dn,
144 144 :firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
145 145 :lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
146 146 :mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
147 147 :auth_source_id => self.id
148 148 }
149 149 end
150 150
151 151 # Return the attributes needed for the LDAP search. It will only
152 152 # include the user attributes if on-the-fly registration is enabled
153 153 def search_attributes
154 154 if onthefly_register?
155 155 ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]
156 156 else
157 157 ['dn']
158 158 end
159 159 end
160 160
161 161 # Check if a DN (user record) authenticates with the password
162 162 def authenticate_dn(dn, password)
163 163 if dn.present? && password.present?
164 164 initialize_ldap_con(dn, password).bind
165 165 end
166 166 end
167 167
168 168 # Get the user's dn and any attributes for them, given their login
169 169 def get_user_dn(login, password)
170 170 ldap_con = nil
171 171 if self.account && self.account.include?("$login")
172 172 ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password)
173 173 else
174 174 ldap_con = initialize_ldap_con(self.account, self.account_password)
175 175 end
176 176 attrs = {}
177 177 search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login)
178 178 ldap_con.search( :base => self.base_dn,
179 179 :filter => search_filter,
180 180 :attributes=> search_attributes) do |entry|
181 181 if onthefly_register?
182 182 attrs = get_user_attributes_from_ldap_entry(entry)
183 183 else
184 184 attrs = {:dn => entry.dn}
185 185 end
186 186 logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug?
187 187 end
188 188 attrs
189 189 end
190 190
191 191 def self.get_attr(entry, attr_name)
192 192 if !attr_name.blank?
193 193 entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
194 194 end
195 195 end
196 196 end
General Comments 0
You need to be logged in to leave comments. Login now